Example #1
0
// 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
}
Example #2
0
// 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()
}
Example #3
0
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
}
Example #5
0
// 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
}
Example #6
0
// 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
}
Example #7
0
// 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
}