예제 #1
0
파일: ca.go 프로젝트: pki-io/controller
func (cont *CAController) GetCA(id string) (*x509.CA, error) {
	logger.Debugf("getting CA")
	logger.Tracef("received id '%s", id)

	logger.Debugf("getting CA json '%s' for org '%s'", id, cont.env.controllers.org.OrgId())
	caContainerJson, err := cont.env.api.GetPrivate(cont.env.controllers.org.OrgId(), id)
	if err != nil {
		return nil, err
	}

	logger.Debug("creating new container from json")
	caContainer, err := document.NewContainer(caContainerJson)
	if err != nil {
		return nil, err
	}

	logger.Debug("decrypting container")
	caJson, err := cont.env.controllers.org.org.VerifyThenDecrypt(caContainer)
	if err != nil {
		return nil, err
	}

	logger.Debug("loading CA json to struct")
	ca, err := x509.NewCA(caJson)
	if err != nil {
		return nil, err
	}

	logger.Trace("returning CA")
	return ca, nil
}
예제 #2
0
파일: org.go 프로젝트: pki-io/controller
func (cont *OrgController) GetCA(id string) (*x509.CA, error) {
	logger.Debug("getting CA")
	logger.Tracef("received CA id '%s'", id)

	org := cont.env.controllers.org.org
	caContainerJson, err := cont.env.api.GetPrivate(org.Id(), id)
	if err != nil {
		return nil, err
	}

	logger.Debug("creating CA container")
	caContainer, err := document.NewContainer(caContainerJson)
	if err != nil {
		return nil, err
	}

	logger.Debug("verifying and decrypting CA container")
	caJson, err := org.VerifyThenDecrypt(caContainer)
	if err != nil {
		return nil, err
	}

	logger.Debug("creating new CA from JSON")
	ca, err := x509.NewCA(caJson)
	if err != nil {
		return nil, err
	}

	logger.Trace("returning CA")
	return ca, nil
}
예제 #3
0
파일: adminApp.go 프로젝트: jawher/admin
func (app *AdminApp) GetCA(id string) *x509.CA {
	logger.Info("Getting CA")
	caContainerJson, err := app.fs.api.GetPrivate(app.entities.org.Data.Body.Id, id)
	caContainer, err := document.NewContainer(caContainerJson)
	checkAppFatal("Couldn't create container from json: %s", err)

	caJson, err := app.entities.org.VerifyThenDecrypt(caContainer)
	checkAppFatal("Couldn't verify and decrypt ca container: %s", err)

	ca, err := x509.NewCA(caJson)
	checkAppFatal("Couldn't create ca: %s", err)
	return ca
}
예제 #4
0
파일: runCert.go 프로젝트: jawher/admin
func certNew(argv map[string]interface{}) (err error) {
	// TODO - this whole function needs to be refactored
	name := ArgString(argv["<name>"], nil)
	exportFile := ArgString(argv["--export"], nil)
	expiry := ArgInt(argv["--expiry"], 365)

	caName := ArgString(argv["--ca"], "")

	dnLocality := ArgString(argv["--dn-l"], "")
	dnState := ArgString(argv["--dn-st"], "")
	dnOrg := ArgString(argv["--dn-o"], "")
	dnOrgUnit := ArgString(argv["--dn-ou"], "")
	dnCountry := ArgString(argv["--dn-c"], "")
	dnStreet := ArgString(argv["--dn-street"], "")
	dnPostal := ArgString(argv["--dn-postal"], "")

	// TODO - This should really be in a certificate function
	subject := pkix.Name{CommonName: name}

	if dnLocality != "" {
		subject.Locality = []string{dnLocality}
	}
	if dnState != "" {
		subject.Province = []string{dnState}
	}
	if dnOrg != "" {
		subject.Organization = []string{dnOrg}
	}
	if dnOrgUnit != "" {
		subject.OrganizationalUnit = []string{dnOrgUnit}
	}
	if dnCountry != "" {
		subject.Country = []string{dnCountry}
	}
	if dnStreet != "" {
		subject.StreetAddress = []string{dnStreet}
	}
	if dnPostal != "" {
		subject.PostalCode = []string{dnPostal}
	}

	cert, err := x509.NewCertificate(nil)
	checkAppFatal("Couldn't create new certificate: %s", err)

	cert.Data.Body.Name = name
	cert.Data.Body.Expiry = expiry

	var files []ExportFile
	certFile := fmt.Sprintf("%s-cert.pem", cert.Data.Body.Name)
	keyFile := fmt.Sprintf("%s-key.pem", cert.Data.Body.Name)

	caFile := fmt.Sprintf("%s-cacert.pem", cert.Data.Body.Name)
	if caName == "" {
		// Self-signed
		err := cert.Generate(nil, &subject)
		checkAppFatal("Couldn't generate certificate: %s", err)

		files = append(files, ExportFile{Name: caFile, Mode: 0644, Content: []byte(cert.Data.Body.Certificate)})
	} else {
		app := NewAdminApp()
		app.Load()
		app.LoadOrgIndex()

		caId, err := app.index.org.GetCA(caName)
		checkUserFatal("Couldn't find CA '%s'%.0s", caName, err)

		caContainerJson, err := app.fs.api.GetPrivate(app.entities.org.Data.Body.Id, caId)
		caContainer, err := document.NewContainer(caContainerJson)
		checkAppFatal("Couldn't create container from json: %s", err)

		caJson, err := app.entities.org.VerifyThenDecrypt(caContainer)
		checkAppFatal("Couldn't verify and decrypt ca container: %s", err)

		ca, err := x509.NewCA(caJson)
		checkAppFatal("Couldn't create ca: %s", err)

		err = cert.Generate(ca, &subject)
		checkAppFatal("Couldn't generate certificate: %s", err)
		files = append(files, ExportFile{Name: caFile, Mode: 0644, Content: []byte(ca.Data.Body.Certificate)})
	}

	files = append(files, ExportFile{Name: certFile, Mode: 0644, Content: []byte(cert.Data.Body.Certificate)})
	files = append(files, ExportFile{Name: keyFile, Mode: 0600, Content: []byte(cert.Data.Body.PrivateKey)})

	if caName == "" {
	} else {
	}

	logger.Infof("Export to '%s'", exportFile)
	Export(files, exportFile)

	return nil
}
예제 #5
0
파일: runCA.go 프로젝트: jawher/admin
func caImport(argv map[string]interface{}) (err error) {
	name := ArgString(argv["<name>"], nil)
	inTags := ArgString(argv["--tags"], nil)

	certFile := ArgString(argv["<cert>"], nil)
	keyFile := ArgString(argv["<privateKey>"], "")

	certExpiry := ArgInt(argv["--cert-expiry"], 90)

	dnLocality := ArgString(argv["--dn-l"], "")
	dnState := ArgString(argv["--dn-st"], "")
	dnOrg := ArgString(argv["--dn-o"], "")
	dnOrgUnit := ArgString(argv["--dn-ou"], "")
	dnCountry := ArgString(argv["--dn-c"], "")
	dnStreet := ArgString(argv["--dn-street"], "")
	dnPostal := ArgString(argv["--dn-postal"], "")

	logger.Infof("Importing %s as %s", certFile, name)
	app := NewAdminApp()
	app.Load()

	ca, _ := x509.NewCA(nil)
	ca.Data.Body.Name = name

	if dnLocality != "" {
		ca.Data.Body.DNScope.Locality = dnLocality
	}
	if dnState != "" {
		ca.Data.Body.DNScope.Province = dnState
	}
	if dnOrg != "" {
		ca.Data.Body.DNScope.Organization = dnOrg
	}
	if dnOrgUnit != "" {
		ca.Data.Body.DNScope.OrganizationalUnit = dnOrgUnit
	}
	if dnCountry != "" {
		ca.Data.Body.DNScope.Country = dnCountry
	}
	if dnStreet != "" {
		ca.Data.Body.DNScope.StreetAddress = dnStreet
	}
	if dnPostal != "" {
		ca.Data.Body.DNScope.PostalCode = dnPostal
	}

	ok, err := fs.Exists(certFile)
	checkAppFatal("Could not check file existence for %s: %s", certFile, err)
	if !ok {
		checkUserFatal("File does not exist: %s", certFile)
	}
	certPem, err := fs.ReadFile(certFile)

	cert, err := x509.PemDecodeX509Certificate([]byte(certPem))
	checkUserFatal("Not a valid certificate PEM for %s: %s", certFile, err)
	// TODO - consider converting cert back to pem to use for consistency

	// We generate a random ID instead of using the serial number because we
	// don't control the serial
	ca.Data.Body.Id = NewID()
	ca.Data.Body.Certificate = certPem
	ca.Data.Body.CertExpiry = certExpiry
	caExpiry := int(cert.NotAfter.Sub(cert.NotBefore) / (time.Hour * 24))
	ca.Data.Body.CAExpiry = caExpiry

	if keyFile != "" {
		ok, err = fs.Exists(keyFile)
		checkAppFatal("Could not check file existence for %s: %s", keyFile, err)
		if !ok {
			checkUserFatal("File does not exist: %s", keyFile)
		}
		keyPem, err := fs.ReadFile(keyFile)

		key, err := crypto.PemDecodePrivate([]byte(keyPem))
		checkUserFatal("Not a valid private key PEM for %s: %s", keyFile, err)
		// TODO - consider converting key back to pem to use for consistency

		keyType, err := crypto.GetKeyType(key)
		checkUserFatal("Unknow private key file for %s: %s", keyFile, err)

		ca.Data.Body.KeyType = string(keyType)
		ca.Data.Body.PrivateKey = keyPem
	}

	logger.Info("Saving CA")
	caContainer, err := app.entities.org.EncryptThenSignString(ca.Dump(), nil)
	checkAppFatal("Could not encrypt CA: %s", err)

	err = app.fs.api.Authenticate(app.entities.org.Data.Body.Id, "")
	checkAppFatal("Could not authenticate to API as Org: %s", err)

	err = app.fs.api.StorePrivate(ca.Data.Body.Id, caContainer.Dump())
	checkAppFatal("Could not save CA: %s", err)

	logger.Info("Updating index")
	app.LoadOrgIndex()
	app.index.org.AddCA(ca.Data.Body.Name, ca.Data.Body.Id)
	app.index.org.AddCATags(ca.Data.Body.Id, ParseTags(inTags))
	app.SaveOrgIndex()

	return nil
}
예제 #6
0
파일: runCA.go 프로젝트: jawher/admin
func caNew(argv map[string]interface{}) (err error) {
	name := ArgString(argv["<name>"], nil)
	inTags := ArgString(argv["--tags"], nil)

	caExpiry := ArgInt(argv["--ca-expiry"], 365)
	certExpiry := ArgInt(argv["--cert-expiry"], 90)

	dnLocality := ArgString(argv["--dn-l"], "")
	dnState := ArgString(argv["--dn-st"], "")
	dnOrg := ArgString(argv["--dn-o"], "")
	dnOrgUnit := ArgString(argv["--dn-ou"], "")
	dnCountry := ArgString(argv["--dn-c"], "")
	dnStreet := ArgString(argv["--dn-street"], "")
	dnPostal := ArgString(argv["--dn-postal"], "")

	app := NewAdminApp()
	app.Load()

	ca, _ := x509.NewCA(nil)
	ca.Data.Body.Name = name
	ca.Data.Body.CAExpiry = caExpiry
	ca.Data.Body.CertExpiry = certExpiry

	if dnLocality != "" {
		ca.Data.Body.DNScope.Locality = dnLocality
	}
	if dnState != "" {
		ca.Data.Body.DNScope.Province = dnState
	}
	if dnOrg != "" {
		ca.Data.Body.DNScope.Organization = dnOrg
	}
	if dnOrgUnit != "" {
		ca.Data.Body.DNScope.OrganizationalUnit = dnOrgUnit
	}
	if dnCountry != "" {
		ca.Data.Body.DNScope.Country = dnCountry
	}
	if dnStreet != "" {
		ca.Data.Body.DNScope.StreetAddress = dnStreet
	}
	if dnPostal != "" {
		ca.Data.Body.DNScope.PostalCode = dnPostal
	}

	ca.GenerateRoot()

	logger.Info("Saving CA")
	caContainer, err := app.entities.org.EncryptThenSignString(ca.Dump(), nil)
	checkAppFatal("Could not encrypt CA: %s", err)

	err = app.fs.api.Authenticate(app.entities.org.Data.Body.Id, "")
	checkAppFatal("Could not authenticate to API as Org: %s", err)

	err = app.fs.api.StorePrivate(ca.Data.Body.Id, caContainer.Dump())
	checkAppFatal("Could not save CA: %s", err)

	logger.Info("Updating index")
	app.LoadOrgIndex()
	app.index.org.AddCA(ca.Data.Body.Name, ca.Data.Body.Id)
	app.index.org.AddCATags(ca.Data.Body.Id, ParseTags(inTags))
	app.SaveOrgIndex()

	return nil
}
예제 #7
0
파일: ca.go 프로젝트: pki-io/controller
func (cont *CAController) New(params *CAParams) (*x509.CA, error) {
	logger.Debug("creating new CA")
	logger.Trace("received params [NOT LOGGED]")

	if err := params.ValidateName(true); err != nil {
		return nil, err
	}

	if err := params.ValidateCAExpiry(true); err != nil {
		return nil, err
	}

	if err := params.ValidateCertExpiry(true); err != nil {
		return nil, err
	}

	if err := params.ValidateKeyType(true); err != nil {
		return nil, err
	}

	if err := cont.env.LoadAdminEnv(); err != nil {
		return nil, err
	}

	logger.Debug("creating CA struct")
	ca, err := x509.NewCA(nil)
	if err != nil {
		return nil, err
	}

	ca.Data.Body.Name = *params.Name
	ca.Data.Body.CAExpiry = *params.CaExpiry
	ca.Data.Body.CertExpiry = *params.CertExpiry
	ca.Data.Body.KeyType = *params.KeyType
	ca.Data.Body.DNScope.Locality = *params.DnLocality
	ca.Data.Body.DNScope.Province = *params.DnState
	ca.Data.Body.DNScope.Organization = *params.DnOrg
	ca.Data.Body.DNScope.OrganizationalUnit = *params.DnOrgUnit
	ca.Data.Body.DNScope.Country = *params.DnCountry
	ca.Data.Body.DNScope.StreetAddress = *params.DnStreet
	ca.Data.Body.DNScope.PostalCode = *params.DnPostal

	if *params.CertFile == "" && *params.KeyFile == "" {
		logger.Debug("generating keys")
		ca.GenerateRoot()
	} else {
		if *params.CertFile == "" {
			return nil, fmt.Errorf("certificate PEM file must be provided if importing")
		}

		ok, err := fs.Exists(*params.CertFile)
		if err != nil {
			return nil, err
		}

		if !ok {
			logger.Warnf("certificate file '%s' does not exist", *params.CertFile)
			return nil, nil
		}

		logger.Debugf("reading certificate PEM file '%s", *params.CertFile)
		certPem, err := fs.ReadFile(*params.CertFile)
		if err != nil {
			return nil, err
		}

		logger.Debug("decoding certificate PEM")
		cert, err := x509.PemDecodeX509Certificate([]byte(certPem))
		if err != nil {
			return nil, err
		}

		ca.Data.Body.Id = x509.NewID()
		ca.Data.Body.Certificate = certPem
		ca.Data.Body.CertExpiry = *params.CertExpiry
		caExpiry := int(cert.NotAfter.Sub(cert.NotBefore) / (time.Hour * 24))
		ca.Data.Body.CAExpiry = caExpiry

		if *params.KeyFile != "" {
			ok, err = fs.Exists(*params.KeyFile)
			if err != nil {
				return nil, err
			}

			if !ok {
				logger.Warnf("key file '%s' does not exist", *params.KeyFile)
				return nil, nil
			}

			logger.Debugf("reading private key PEM file '%s'", *params.KeyFile)
			keyPem, err := fs.ReadFile(*params.KeyFile)
			if err != nil {
				return nil, err
			}

			logger.Debug("decoding private key")
			key, err := crypto.PemDecodePrivate([]byte(keyPem))
			if err != nil {
				return nil, err
			}

			logger.Debug("getting key type")
			keyType, err := crypto.GetKeyType(key)
			if err != nil {
				return nil, err
			}

			ca.Data.Body.KeyType = string(keyType)
			ca.Data.Body.PrivateKey = keyPem
		}
	}

	err = cont.SaveCA(ca)
	if err != nil {
		return nil, err
	}

	err = cont.AddCAToOrgIndex(ca, *params.Tags)
	if err != nil {
		return nil, err
	}

	logger.Trace("returning CA")
	return ca, nil
}