func TestECDSAKeyImportFromECDSAPublicKey(t *testing.T) { // Generate an ECDSA key k, err := currentBCCSP.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false}) if err != nil { t.Fatalf("Failed generating ECDSA key [%s]", err) } // Export the public key pk, err := k.PublicKey() if err != nil { t.Fatalf("Failed getting ECDSA public key [%s]", err) } pkRaw, err := pk.Bytes() if err != nil { t.Fatalf("Failed getting ECDSA raw public key [%s]", err) } pub, err := utils.DERToPublicKey(pkRaw) if err != nil { t.Fatalf("Failed converting raw to ecdsa.PublicKey [%s]", err) } // Import the ecdsa.PublicKey pk2, err := currentBCCSP.KeyImport(pub, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: false}) if err != nil { t.Fatalf("Failed importing ECDSA public key [%s]", err) } if pk2 == nil { t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.") } // Sign and verify with the imported public key msg := []byte("Hello World") digest, err := currentBCCSP.Hash(msg, &bccsp.SHAOpts{}) if err != nil { t.Fatalf("Failed computing HASH [%s]", err) } signature, err := currentBCCSP.Sign(k, digest, nil) if err != nil { t.Fatalf("Failed generating ECDSA signature [%s]", err) } valid, err := currentBCCSP.Verify(pk2, signature, digest, nil) if err != nil { t.Fatalf("Failed verifying ECDSA signature [%s]", err) } if !valid { t.Fatal("Failed verifying ECDSA signature. Signature not valid.") } }
// Init initializes this CryptoSigner. func (s *CryptoSigner) Init(csp bccsp.BCCSP, key bccsp.Key) error { // Validate arguments if csp == nil { return errors.New("Invalid BCCSP. Nil.") } if key == nil { return errors.New("Invalid Key. Nil.") } if key.Symmetric() { return errors.New("Invalid Key. Symmetric.") } // Marshall the bccsp public key as a crypto.PublicKey pub, err := key.PublicKey() if err != nil { return fmt.Errorf("Failed getting public key [%s]", err) } raw, err := pub.Bytes() if err != nil { return fmt.Errorf("Failed marshalling public key [%s]", err) } pk, err := utils.DERToPublicKey(raw) if err != nil { return fmt.Errorf("Failed marshalling public key [%s]", err) } // Init fields s.csp = csp s.key = key s.pk = pk return nil }
func TestKeyImportFromX509ECDSAPublicKey(t *testing.T) { // Generate an ECDSA key k, err := currentBCCSP.KeyGen(&bccsp.ECDSAKeyGenOpts{Temporary: false}) if err != nil { t.Fatalf("Failed generating ECDSA key [%s]", err) } // Generate a self-signed certificate testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} extraExtensionData := []byte("extra extension") commonName := "test.example.com" template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: commonName, Organization: []string{"Σ Acme Co"}, Country: []string{"US"}, ExtraNames: []pkix.AttributeTypeAndValue{ { Type: []int{2, 5, 4, 42}, Value: "Gopher", }, // This should override the Country, above. { Type: []int{2, 5, 4, 6}, Value: "NL", }, }, }, NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(1 * time.Hour), SignatureAlgorithm: x509.ECDSAWithSHA256, SubjectKeyId: []byte{1, 2, 3, 4}, KeyUsage: x509.KeyUsageCertSign, ExtKeyUsage: testExtKeyUsage, UnknownExtKeyUsage: testUnknownExtKeyUsage, BasicConstraintsValid: true, IsCA: true, OCSPServer: []string{"http://ocurrentBCCSP.example.com"}, IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, DNSNames: []string{"test.example.com"}, EmailAddresses: []string{"*****@*****.**"}, IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}}, PermittedDNSDomains: []string{".example.com", "example.com"}, CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, ExtraExtensions: []pkix.Extension{ { Id: []int{1, 2, 3, 4}, Value: extraExtensionData, }, }, } cryptoSigner := &signer.CryptoSigner{} err = cryptoSigner.Init(currentBCCSP, k) if err != nil { t.Fatalf("Failed initializing CyrptoSigner [%s]", err) } // Export the public key pk, err := k.PublicKey() if err != nil { t.Fatalf("Failed getting ECDSA public key [%s]", err) } pkRaw, err := pk.Bytes() if err != nil { t.Fatalf("Failed getting ECDSA raw public key [%s]", err) } pub, err := utils.DERToPublicKey(pkRaw) if err != nil { t.Fatalf("Failed converting raw to ECDSA.PublicKey [%s]", err) } certRaw, err := x509.CreateCertificate(rand.Reader, &template, &template, pub, cryptoSigner) if err != nil { t.Fatalf("Failed generating self-signed certificate [%s]", err) } cert, err := utils.DERToX509Certificate(certRaw) if err != nil { t.Fatalf("Failed generating X509 certificate object from raw [%s]", err) } // Import the certificate's public key pk2, err := currentBCCSP.KeyImport(cert, &bccsp.X509PublicKeyImportOpts{Temporary: false}) if err != nil { t.Fatalf("Failed importing ECDSA public key [%s]", err) } if pk2 == nil { t.Fatal("Failed importing ECDSA public key. Return BCCSP key cannot be nil.") } // Sign and verify with the imported public key msg := []byte("Hello World") digest, err := currentBCCSP.Hash(msg, &bccsp.SHAOpts{}) if err != nil { t.Fatalf("Failed computing HASH [%s]", err) } signature, err := currentBCCSP.Sign(k, digest, nil) if err != nil { t.Fatalf("Failed generating ECDSA signature [%s]", err) } valid, err := currentBCCSP.Verify(pk2, signature, digest, nil) if err != nil { t.Fatalf("Failed verifying ECDSA signature [%s]", err) } if !valid { t.Fatal("Failed verifying ECDSA signature. Signature not valid.") } }
// KeyImport imports a key from its raw representation using opts. // The opts argument should be appropriate for the primitive used. func (csp *impl) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { // Validate arguments if raw == nil { return nil, errors.New("Invalid raw. Cannot be nil") } if opts == nil { return nil, errors.New("Invalid Opts parameter. It must not be nil.") } switch opts.(type) { case *bccsp.AES256ImportKeyOpts: aesRaw, ok := raw.([]byte) if !ok { return nil, errors.New("[AES256ImportKeyOpts] Invalid raw material. Expected byte array.") } if len(aesRaw) != 32 { return nil, fmt.Errorf("[AES256ImportKeyOpts] Invalid Key Length [%d]. Must be 32 bytes", len(aesRaw)) } aesK := &aesPrivateKey{utils.Clone(aesRaw), false} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(aesK) if err != nil { return nil, fmt.Errorf("Failed storing AES key [%s]", err) } } return aesK, nil case *bccsp.HMACImportKeyOpts: aesRaw, ok := raw.([]byte) if !ok { return nil, errors.New("[HMACImportKeyOpts] Invalid raw material. Expected byte array.") } if len(aesRaw) == 0 { return nil, errors.New("[HMACImportKeyOpts] Invalid raw. It must not be nil.") } aesK := &aesPrivateKey{utils.Clone(aesRaw), false} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(aesK) if err != nil { return nil, fmt.Errorf("Failed storing AES key [%s]", err) } } return aesK, nil case *bccsp.ECDSAPKIXPublicKeyImportOpts: der, ok := raw.([]byte) if !ok { return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw material. Expected byte array.") } if len(der) == 0 { return nil, errors.New("[ECDSAPKIXPublicKeyImportOpts] Invalid raw. It must not be nil.") } lowLevelKey, err := utils.DERToPublicKey(der) if err != nil { return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err) } ecdsaPK, ok := lowLevelKey.(*ecdsa.PublicKey) if !ok { return nil, errors.New("Failed casting to ECDSA public key. Invalid raw material.") } k = &ecdsaPublicKey{ecdsaPK} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(k) if err != nil { return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) } } return k, nil case *bccsp.ECDSAPrivateKeyImportOpts: der, ok := raw.([]byte) if !ok { return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw material. Expected byte array.") } if len(der) == 0 { return nil, errors.New("[ECDSADERPrivateKeyImportOpts] Invalid raw. It must not be nil.") } lowLevelKey, err := utils.DERToPrivateKey(der) if err != nil { return nil, fmt.Errorf("Failed converting PKIX to ECDSA public key [%s]", err) } ecdsaSK, ok := lowLevelKey.(*ecdsa.PrivateKey) if !ok { return nil, errors.New("Failed casting to ECDSA public key. Invalid raw material.") } k = &ecdsaPrivateKey{ecdsaSK} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(k) if err != nil { return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) } } return k, nil case *bccsp.ECDSAGoPublicKeyImportOpts: lowLevelKey, ok := raw.(*ecdsa.PublicKey) if !ok { return nil, errors.New("[ECDSAGoPublicKeyImportOpts] Invalid raw material. Expected *ecdsa.PublicKey.") } k = &ecdsaPublicKey{lowLevelKey} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(k) if err != nil { return nil, fmt.Errorf("Failed storing ECDSA key [%s]", err) } } return k, nil case *bccsp.RSAGoPublicKeyImportOpts: lowLevelKey, ok := raw.(*rsa.PublicKey) if !ok { return nil, errors.New("[RSAGoPublicKeyImportOpts] Invalid raw material. Expected *rsa.PublicKey.") } k = &rsaPublicKey{lowLevelKey} // If the key is not Ephemeral, store it. if !opts.Ephemeral() { // Store the key err = csp.ks.StoreKey(k) if err != nil { return nil, fmt.Errorf("Failed storing RSA publi key [%s]", err) } } return k, nil case *bccsp.X509PublicKeyImportOpts: x509Cert, ok := raw.(*x509.Certificate) if !ok { return nil, errors.New("[X509PublicKeyImportOpts] Invalid raw material. Expected *x509.Certificate.") } pk := x509Cert.PublicKey switch pk.(type) { case *ecdsa.PublicKey: return csp.KeyImport(pk, &bccsp.ECDSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) case *rsa.PublicKey: return csp.KeyImport(pk, &bccsp.RSAGoPublicKeyImportOpts{Temporary: opts.Ephemeral()}) default: return nil, errors.New("Certificate public key type not recognized. Supported keys: [ECDSA, RSA]") } default: return nil, errors.New("Import Key Options not recognized") } }