// GenerateCertificate generates an X509 Certificate from a template, given a GUN func GenerateCertificate(rootKey data.PrivateKey, gun string) (*x509.Certificate, error) { switch rootKey.(type) { case *data.RSAPrivateKey, *data.ECDSAPrivateKey: // go doesn't fall through default: return nil, fmt.Errorf("only bare RSA or ECDSA keys (not x509 variants) are currently supported. Found: %s", rootKey.Algorithm()) } template, err := trustmanager.NewCertificate(gun) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, rootKey.CryptoSigner().Public(), rootKey.CryptoSigner()) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } // Encode the new certificate into PEM cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// generates a multiple-certificate file with both RSA and ECDSA certs and // returns the filename so that cleanup can be deferred. func generateMultiCert(t *testing.T) string { tempFile, err := ioutil.TempFile("/tmp", "cert-test") defer tempFile.Close() assert.NoError(t, err) rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) assert.NoError(t, err) ecKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) assert.NoError(t, err) template, err := trustmanager.NewCertificate("gun") assert.NoError(t, err) for _, key := range []crypto.Signer{rsaKey, ecKey} { derBytes, err := x509.CreateCertificate( rand.Reader, template, template, key.Public(), key) assert.NoError(t, err) cert, err := x509.ParseCertificate(derBytes) assert.NoError(t, err) pemBytes := trustmanager.CertToPEM(cert) nBytes, err := tempFile.Write(pemBytes) assert.NoError(t, err) assert.Equal(t, nBytes, len(pemBytes)) } return tempFile.Name() }
func generateCertificate(signer crypto.Signer, gun string, startTime, endTime time.Time) (*x509.Certificate, error) { template, err := trustmanager.NewCertificate(gun, startTime, endTime) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, signer.Public(), signer) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// GenerateCertificate generates an X509 Certificate from a template, given a GUN func (ucs *UnlockedCryptoService) GenerateCertificate(gun string) (*x509.Certificate, error) { algorithm := ucs.PrivKey.Algorithm() var publicKey crypto.PublicKey var privateKey crypto.PrivateKey var err error switch algorithm { case data.RSAKey: var rsaPrivateKey *rsa.PrivateKey rsaPrivateKey, err = x509.ParsePKCS1PrivateKey(ucs.PrivKey.Private()) privateKey = rsaPrivateKey publicKey = rsaPrivateKey.Public() case data.ECDSAKey: var ecdsaPrivateKey *ecdsa.PrivateKey ecdsaPrivateKey, err = x509.ParseECPrivateKey(ucs.PrivKey.Private()) privateKey = ecdsaPrivateKey publicKey = ecdsaPrivateKey.Public() default: return nil, fmt.Errorf("only RSA or ECDSA keys are currently supported. Found: %s", algorithm) } if err != nil { return nil, fmt.Errorf("failed to parse root key: %s (%v)", gun, err) } template, err := trustmanager.NewCertificate(gun) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, publicKey, privateKey) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } // Encode the new certificate into PEM cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// GenerateCertificate generates an X509 Certificate from a template, given a GUN func GenerateCertificate(rootKey data.PrivateKey, gun string) (*x509.Certificate, error) { signer := rootKey.CryptoSigner() if signer == nil { return nil, fmt.Errorf("key type not supported for Certificate generation: %s\n", rootKey.Algorithm()) } template, err := trustmanager.NewCertificate(gun) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, signer.Public(), signer) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } // Encode the new certificate into PEM cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// GenerateCertificate generates an X509 Certificate from a template, given a GUN func (uk *UnlockedSigner) GenerateCertificate(gun string) (*x509.Certificate, error) { privKey, err := x509.ParsePKCS1PrivateKey(uk.privKey.Private()) if err != nil { return nil, fmt.Errorf("failed to parse root key: %v (%s)", gun, err.Error()) } template, err := trustmanager.NewCertificate(gun) if err != nil { return nil, fmt.Errorf("failed to create the certificate template for: %s (%v)", gun, err) } derBytes, err := x509.CreateCertificate(rand.Reader, template, template, privKey.Public(), privKey) if err != nil { return nil, fmt.Errorf("failed to create the certificate for: %s (%v)", gun, err) } // Encode the new certificate into PEM cert, err := x509.ParseCertificate(derBytes) if err != nil { return nil, fmt.Errorf("failed to parse the certificate for key: %s (%v)", gun, err) } return cert, nil }
// addECDSAKey adds a key to the yubikey func addECDSAKey( ctx IPKCS11Ctx, session pkcs11.SessionHandle, privKey data.PrivateKey, pkcs11KeyID []byte, passRetriever passphrase.Retriever, role string, ) error { logrus.Debugf("Attempting to add key to yubikey with ID: %s", privKey.ID()) err := login(ctx, session, passRetriever, pkcs11.CKU_SO, SO_USER_PIN) if err != nil { return err } defer ctx.Logout(session) // Create an ecdsa.PrivateKey out of the private key bytes ecdsaPrivKey, err := x509.ParseECPrivateKey(privKey.Private()) if err != nil { return err } ecdsaPrivKeyD := ensurePrivateKeySize(ecdsaPrivKey.D.Bytes()) // Hard-coded policy: the generated certificate expires in 10 years. startTime := time.Now() template, err := trustmanager.NewCertificate(role, startTime, startTime.AddDate(10, 0, 0)) if err != nil { return fmt.Errorf("failed to create the certificate template: %v", err) } certBytes, err := x509.CreateCertificate(rand.Reader, template, template, ecdsaPrivKey.Public(), ecdsaPrivKey) if err != nil { return fmt.Errorf("failed to create the certificate: %v", err) } certTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE), pkcs11.NewAttribute(pkcs11.CKA_VALUE, certBytes), pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID), } privateKeyTemplate := []*pkcs11.Attribute{ pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY), pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA), pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID), pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}), pkcs11.NewAttribute(pkcs11.CKA_VALUE, ecdsaPrivKeyD), pkcs11.NewAttribute(pkcs11.CKA_VENDOR_DEFINED, yubikeyKeymode), } _, err = ctx.CreateObject(session, certTemplate) if err != nil { return fmt.Errorf("error importing: %v", err) } _, err = ctx.CreateObject(session, privateKeyTemplate) if err != nil { return fmt.Errorf("error importing: %v", err) } return nil }