Exemplo n.º 1
0
func (cont *CertificateController) GetCert(id string) (*x509.Certificate, error) {
	logger.Debug("getting certificate")
	logger.Tracef("received certificate id '%s'", id)

	logger.Debugf("getting private file '%s' from org", id)
	certContainerJson, err := cont.env.api.GetPrivate(cont.env.controllers.org.org.Data.Body.Id, id)
	if err != nil {
		return nil, err
	}

	logger.Debug("creating new container")
	certContainer, err := document.NewContainer(certContainerJson)
	if err != nil {
		return nil, err
	}

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

	logger.Debug("loading certificate json")
	cert, err := x509.NewCertificate(certJson)
	if err != nil {
		return nil, err
	}

	logger.Trace("returning nil error")
	return cert, nil
}
Exemplo n.º 2
0
func (app *NodeApp) GetCertificate(id string) *x509.Certificate {
	certContainerJson, err := app.fs.api.GetPrivate(app.entities.node.Data.Body.Id, id)
	checkAppFatal("Could not load cert container json: %s", err)

	certContainer, err := document.NewContainer(certContainerJson)
	checkAppFatal("Could not load cert container: %s", err)

	certJson, err := app.entities.node.VerifyThenDecrypt(certContainer)
	checkAppFatal("Could not verify and decrypt: %s", err)

	cert, err := x509.NewCertificate(certJson)
	checkAppFatal("Could not load cert: %s", err)
	return cert
}
Exemplo n.º 3
0
func (app *NodeApp) ProcessNextCert() {
	certContainerJson, err := app.fs.api.PopIncoming("certs")
	checkAppFatal("Can't pop cert: %s", err)

	certContainer, err := document.NewContainer(certContainerJson)
	checkAppFatal("Can't create cert container: %s", err)

	err = app.entities.org.Verify(certContainer)
	checkAppFatal("Cert didn't verify: %s", err)

	cert, err := x509.NewCertificate(certContainer.Data.Body)
	checkAppFatal("Can't load certificate: %s", err)

	csrContainerJson, err := app.fs.api.GetPrivate(app.entities.node.Data.Body.Id, cert.Data.Body.Id)
	checkAppFatal("Couldn't load csr file: %s", err)

	csrContainer, err := document.NewContainer(csrContainerJson)
	checkAppFatal("Couldn't load CSR container: %s", err)

	csrJson, err := app.entities.node.VerifyThenDecrypt(csrContainer)
	checkAppFatal("Couldn't verify and decrypt container: %s", err)

	csr, err := x509.NewCSR(csrJson)
	checkAppFatal("Couldn't load csr: %s", err)

	// Set the private key from the csr
	cert.Data.Body.PrivateKey = csr.Data.Body.PrivateKey

	updatedCertContainer, err := app.entities.node.EncryptThenSignString(cert.Dump(), nil)
	checkAppFatal("Could not encrypt then sign cert: %s", err)

	err = app.fs.api.SendPrivate(app.entities.node.Data.Body.Id, cert.Data.Body.Id, updatedCertContainer.Dump())
	checkAppFatal("Could save cert: %s", err)

	err = app.index.node.AddCertTags(cert.Data.Body.Id, cert.Data.Body.Tags)
	checkAppFatal("Could not add cert tags: %s", err)
}
Exemplo n.º 4
0
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
}
Exemplo n.º 5
0
func (cont *NodeController) ProcessNextCert() error {
	logger.Debug("processing next certificate")

	logger.Debug("getting next incoming certificate JSON")
	certContainerJson, err := cont.env.api.PopIncoming(cont.node.Data.Body.Id, "certs")
	if err != nil {
		return err
	}

	logger.Debug("creating certificate container from JSON")
	certContainer, err := document.NewContainer(certContainerJson)
	if err != nil {
		return err
	}

	logger.Debug("verifying container is signed by org")
	if err := cont.env.controllers.org.org.Verify(certContainer); err != nil {
		return err
	}

	logger.Debug("creating new certificate struct")
	cert, err := x509.NewCertificate(certContainer.Data.Body)
	if err != nil {
		return err
	}

	logger.Debugf("getting matching CSR for id '%s'", cert.Data.Body.Id)
	csrContainerJson, err := cont.env.api.GetPrivate(cont.node.Data.Body.Id, cert.Data.Body.Id)
	if err != nil {
		return err
	}

	logger.Debug("creating CSR container")
	csrContainer, err := document.NewContainer(csrContainerJson)
	if err != nil {
		return err
	}

	logger.Debug("verifying and decryping CSR container")
	csrJson, err := cont.node.VerifyThenDecrypt(csrContainer)
	if err != nil {
		return err
	}

	logger.Debug("creating CSR struct from JSON")
	csr, err := x509.NewCSR(csrJson)
	if err != nil {
		return err
	}

	logger.Debug("setting new ID for certificate")
	cert.Data.Body.Id = x509.NewID()

	logger.Debug("setting certificate private key from CSR")
	cert.Data.Body.PrivateKey = csr.Data.Body.PrivateKey

	logger.Debug("encrypting and signing certificate for node")
	updatedCertContainer, err := cont.node.EncryptThenSignString(cert.Dump(), nil)
	if err != nil {
		return err
	}

	logger.Debug("saving encrypted certificate for node")
	if err := cont.env.api.SendPrivate(cont.node.Data.Body.Id, cert.Data.Body.Id, updatedCertContainer.Dump()); err != nil {
		return err
	}

	logger.Trace("returning nil error")
	return nil
}
Exemplo n.º 6
0
func (cont *CertificateController) New(params *CertificateParams) (*x509.Certificate, *x509.CA, error) {
	logger.Debug("creating new certificate")
	logger.Tracef("received params: %s", params)

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

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

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

	if *params.DnLocality != "" {
		subject.Locality = []string{*params.DnLocality}
	}
	if *params.DnState != "" {
		subject.Province = []string{*params.DnState}
	}
	if *params.DnOrg != "" {
		subject.Organization = []string{*params.DnOrg}
	}
	if *params.DnOrgUnit != "" {
		subject.OrganizationalUnit = []string{*params.DnOrgUnit}
	}
	if *params.DnCountry != "" {
		subject.Country = []string{*params.DnCountry}
	}
	if *params.DnStreet != "" {
		subject.StreetAddress = []string{*params.DnStreet}
	}
	if *params.DnPostal != "" {
		subject.PostalCode = []string{*params.DnPostal}
	}

	logger.Debug("creating certificate struct")
	cert, err := x509.NewCertificate(nil)
	if err != nil {
		return nil, nil, err
	}

	cert.Data.Body.Name = *params.Name
	cert.Data.Body.Expiry = *params.Expiry

	var ca *x509.CA

	if *params.CertFile == "" && *params.KeyFile == "" {
		cert.Data.Body.KeyType = *params.KeyType
		logger.Debug("generating certificate and key")
		if *params.Ca == "" {
			if err := cert.Generate(nil, &subject); err != nil {
				return nil, nil, err
			}
		} else {
			index, err := cont.env.controllers.org.GetIndex()
			if err != nil {
				return nil, nil, err
			}

			caId, err := index.GetCA(*params.Ca)
			if err != nil {
				return nil, nil, err
			}

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

			logger.Debugf("generating certificate and signing with CA '%s'", caId)
			if err := cert.Generate(ca, &subject); err != nil {
				return nil, nil, err
			}
		}
	} else {
		if *params.CertFile == "" {
			return nil, nil, fmt.Errorf("certificate PEM file must be provided if importing")
		}

		logger.Debugf("importing certificate from '%s'", *params.CertFile)
		ok, err := fs.Exists(*params.CertFile)
		if err != nil {
			return nil, nil, err
		}

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

		logger.Debug("reading certificate from file")
		certPem, err := fs.ReadFile(*params.CertFile)
		if err != nil {
			return nil, nil, err
		}

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

		cert.Data.Body.Id = x509.NewID()
		cert.Data.Body.Certificate = certPem
		certExpiry := int(importCert.NotAfter.Sub(importCert.NotBefore) / (time.Hour * 24))
		cert.Data.Body.Expiry = certExpiry

		if *params.KeyFile != "" {
			logger.Debugf("importing certificate privte key from '%s'", *params.KeyFile)
			ok, err := fs.Exists(*params.KeyFile)
			if err != nil {
				return nil, nil, err
			}

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

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

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

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

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

	if *params.StandaloneFile == "" {
		err = cont.SaveCert(cert)
		if err != nil {
			return nil, nil, err
		}

		var tags string
		if *params.Tags == "NAME" {
			tags = *params.Name
		} else {
			tags = *params.Tags
		}

		err = cont.AddCertToOrgIndex(cert, tags)
		if err != nil {
			return nil, nil, err
		}
	}

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