From 8bf6e09f4cbb0242039dd4602f1f2d58e30e0f26 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Wed, 21 Jan 2015 00:39:53 +0000 Subject: [PATCH] Revert "crypto/x509: implement crypto.Signer" This reverts commit cef15faafe5d15ba6242bad3504a52d287f78b88. Change-Id: I6df3e9ea48cd58893892587dd5cd28c1eb759c48 Reviewed-on: https://go-review.googlesource.com/3090 Reviewed-by: Adam Langley --- src/crypto/x509/x509.go | 106 ++++++++++++++++++++++++----------- src/crypto/x509/x509_test.go | 12 ++-- 2 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go index 9616d54ced..8bad08e5ae 100644 --- a/src/crypto/x509/x509.go +++ b/src/crypto/x509/x509.go @@ -12,7 +12,7 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" - _ "crypto/sha1" + "crypto/sha1" _ "crypto/sha256" _ "crypto/sha512" "crypto/x509/pkix" @@ -1389,14 +1389,14 @@ func subjectBytes(cert *Certificate) ([]byte, error) { return asn1.Marshal(cert.Subject.ToRDNSequence()) } -// signingParamsForPublicKey returns the parameters to use for signing with +// signingParamsForPrivateKey returns the parameters to use for signing with // priv. If requestedSigAlgo is not zero then it overrides the default // signature algorithm. -func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { +func signingParamsForPrivateKey(priv interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { var pubType PublicKeyAlgorithm - switch pub := pub.(type) { - case *rsa.PublicKey: + switch priv := priv.(type) { + case *rsa.PrivateKey: pubType = RSA hashFunc = crypto.SHA256 sigAlgo.Algorithm = oidSignatureSHA256WithRSA @@ -1404,10 +1404,10 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori Tag: 5, } - case *ecdsa.PublicKey: + case *ecdsa.PrivateKey: pubType = ECDSA - switch pub.Curve { + switch priv.Curve { case elliptic.P224(), elliptic.P256(): hashFunc = crypto.SHA256 sigAlgo.Algorithm = oidSignatureECDSAWithSHA256 @@ -1422,7 +1422,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori } default: - err = errors.New("x509: only RSA and ECDSA keys supported") + err = errors.New("x509: only RSA and ECDSA private keys supported") } if err != nil { @@ -1469,10 +1469,10 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgori // // The returned slice is the certificate in DER encoding. // -// All keys types that are implemented via crypto.Signer are supported (This -// includes *rsa.PublicKey and *ecdsa.PublicKey.) -func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv crypto.Signer) (cert []byte, err error) { - hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) +// The only supported key types are RSA and ECDSA (*rsa.PublicKey or +// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv). +func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) { + hashFunc, signatureAlgorithm, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm) if err != nil { return nil, err } @@ -1482,6 +1482,10 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf return nil, err } + if err != nil { + return + } + if len(parent.SubjectKeyId) > 0 { template.AuthorityKeyId = parent.SubjectKeyId } @@ -1525,7 +1529,19 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interf digest := h.Sum(nil) var signature []byte - signature, err = priv.Sign(rand, digest, hashFunc) + + switch priv := priv.(type) { + case *rsa.PrivateKey: + signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest) + case *ecdsa.PrivateKey: + var r, s *big.Int + if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil { + signature, err = asn1.Marshal(ecdsaSignature{r, s}) + } + default: + panic("internal error") + } + if err != nil { return } @@ -1572,15 +1588,18 @@ func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) { // CreateCRL returns a DER encoded CRL, signed by this Certificate, that // contains the given list of revoked certificates. -func (c *Certificate) CreateCRL(rand io.Reader, priv crypto.Signer, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) { - hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), 0) - if err != nil { - return nil, err +// +// The only supported key type is RSA (*rsa.PrivateKey for priv). +func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) { + rsaPriv, ok := priv.(*rsa.PrivateKey) + if !ok { + return nil, errors.New("x509: non-RSA private keys not supported") } - tbsCertList := pkix.TBSCertificateList{ - Version: 1, - Signature: signatureAlgorithm, + Version: 1, + Signature: pkix.AlgorithmIdentifier{ + Algorithm: oidSignatureSHA1WithRSA, + }, Issuer: c.Subject.ToRDNSequence(), ThisUpdate: now.UTC(), NextUpdate: expiry.UTC(), @@ -1603,20 +1622,21 @@ func (c *Certificate) CreateCRL(rand io.Reader, priv crypto.Signer, revokedCerts return } - h := hashFunc.New() + h := sha1.New() h.Write(tbsCertListContents) digest := h.Sum(nil) - var signature []byte - signature, err = priv.Sign(rand, digest, hashFunc) + signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest) if err != nil { return } return asn1.Marshal(pkix.CertificateList{ - TBSCertList: tbsCertList, - SignatureAlgorithm: signatureAlgorithm, - SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, + TBSCertList: tbsCertList, + SignatureAlgorithm: pkix.AlgorithmIdentifier{ + Algorithm: oidSignatureSHA1WithRSA, + }, + SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8}, }) } @@ -1690,19 +1710,26 @@ var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14} // // The returned slice is the certificate request in DER encoding. // -// All keys types that are implemented via crypto.Signer are supported (This -// includes *rsa.PublicKey and *ecdsa.PublicKey.) -func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv crypto.Signer) (csr []byte, err error) { - var hashFunc crypto.Hash - var sigAlgo pkix.AlgorithmIdentifier - hashFunc, sigAlgo, err = signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm) +// The only supported key types are RSA (*rsa.PrivateKey) and ECDSA +// (*ecdsa.PrivateKey). +func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) { + hashFunc, sigAlgo, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm) if err != nil { return nil, err } var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier - publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(priv.Public()) + + switch priv := priv.(type) { + case *rsa.PrivateKey: + publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey) + case *ecdsa.PrivateKey: + publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey) + default: + panic("internal error") + } + if err != nil { return nil, err } @@ -1814,7 +1841,18 @@ func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv digest := h.Sum(nil) var signature []byte - signature, err = priv.Sign(rand, digest, hashFunc) + switch priv := priv.(type) { + case *rsa.PrivateKey: + signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest) + case *ecdsa.PrivateKey: + var r, s *big.Int + if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil { + signature, err = asn1.Marshal(ecdsaSignature{r, s}) + } + default: + panic("internal error") + } + if err != nil { return } diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go index af27731090..f275375ba7 100644 --- a/src/crypto/x509/x509_test.go +++ b/src/crypto/x509/x509_test.go @@ -6,7 +6,6 @@ package x509 import ( "bytes" - "crypto" "crypto/dsa" "crypto/ecdsa" "crypto/elliptic" @@ -305,11 +304,10 @@ func TestCreateSelfSignedCertificate(t *testing.T) { } tests := []struct { - name string - pub interface{} - priv crypto.Signer - checkSig bool - sigAlgo SignatureAlgorithm + name string + pub, priv interface{} + checkSig bool + sigAlgo SignatureAlgorithm }{ {"RSA/RSA", &rsaPriv.PublicKey, rsaPriv, true, SHA1WithRSA}, {"RSA/ECDSA", &rsaPriv.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, @@ -781,7 +779,7 @@ func TestCreateCertificateRequest(t *testing.T) { tests := []struct { name string - priv crypto.Signer + priv interface{} sigAlgo SignatureAlgorithm }{ {"RSA", rsaPriv, SHA1WithRSA},