diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-11 11:13:27 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-11 11:13:27 +0000 |
commit | c41143fb1d63596ff2a0f6da741b4bae73b8be16 (patch) | |
tree | d70c0763693cfef7bc877f21e079986944261a5f /libgo/go/crypto/x509/x509.go | |
parent | eb0badc13724022c8828a55e516d0eecdc487cc3 (diff) | |
download | gcc-c41143fb1d63596ff2a0f6da741b4bae73b8be16.tar.gz |
2011-05-11 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 173647 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@173652 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/crypto/x509/x509.go')
-rw-r--r-- | libgo/go/crypto/x509/x509.go | 176 |
1 files changed, 163 insertions, 13 deletions
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 6199e8db9f5..6825030d6f9 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -9,6 +9,7 @@ import ( "asn1" "big" "container/vector" + "crypto" "crypto/rsa" "crypto/sha1" "hash" @@ -53,20 +54,21 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err os.Error) { return } - key = &rsa.PrivateKey{ - PublicKey: rsa.PublicKey{ - E: priv.E, - N: new(big.Int).SetBytes(priv.N.Bytes), - }, - D: new(big.Int).SetBytes(priv.D.Bytes), - P: new(big.Int).SetBytes(priv.P.Bytes), - Q: new(big.Int).SetBytes(priv.Q.Bytes), + key = new(rsa.PrivateKey) + key.PublicKey = rsa.PublicKey{ + E: priv.E, + N: new(big.Int).SetBytes(priv.N.Bytes), } + key.D = new(big.Int).SetBytes(priv.D.Bytes) + key.P = new(big.Int).SetBytes(priv.P.Bytes) + key.Q = new(big.Int).SetBytes(priv.Q.Bytes) + err = key.Validate() if err != nil { return nil, err } + return } @@ -303,6 +305,42 @@ const ( KeyUsageDecipherOnly ) +// RFC 5280, 4.2.1.12 Extended Key Usage +// +// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } +// +// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } +// +// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } +// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } +// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } +// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } +// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } +// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } +var ( + oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0} + oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1} + oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2} + oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3} + oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4} + oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} + oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9} +) + +// ExtKeyUsage represents an extended set of actions that are valid for a given key. +// Each of the ExtKeyUsage* constants define a unique action. +type ExtKeyUsage int + +const ( + ExtKeyUsageAny ExtKeyUsage = iota + ExtKeyUsageServerAuth + ExtKeyUsageClientAuth + ExtKeyUsageCodeSigning + ExtKeyUsageEmailProtection + ExtKeyUsageTimeStamping + ExtKeyUsageOCSPSigning +) + // A Certificate represents an X.509 certificate. type Certificate struct { Raw []byte // Raw ASN.1 DER contents. @@ -319,6 +357,9 @@ type Certificate struct { NotBefore, NotAfter *time.Time // Validity bounds. KeyUsage KeyUsage + ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages. + UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. + BasicConstraintsValid bool // if true then the next two fields are valid. IsCA bool MaxPathLen int @@ -330,6 +371,10 @@ type Certificate struct { DNSNames []string EmailAddresses []string + // Name constraints + PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. + PermittedDNSDomains []string + PolicyIdentifiers []asn1.ObjectIdentifier } @@ -374,12 +419,12 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err os.Error) { // TODO(agl): don't ignore the path length constraint. var h hash.Hash - var hashType rsa.PKCS1v15Hash + var hashType crypto.Hash switch c.SignatureAlgorithm { case SHA1WithRSA: h = sha1.New() - hashType = rsa.HashSHA1 + hashType = crypto.SHA1 default: return UnsupportedAlgorithmError{} } @@ -474,6 +519,18 @@ type policyInformation struct { // policyQualifiers omitted } +// RFC 5280, 4.2.1.10 +type nameConstraints struct { + Permitted []generalSubtree "optional,tag:0" + Excluded []generalSubtree "optional,tag:1" +} + +type generalSubtree struct { + Name string "tag:2,optional,ia5" + Min int "optional,tag:0" + Max int "optional,tag:1" +} + func parsePublicKey(algo PublicKeyAlgorithm, asn1Data []byte) (interface{}, os.Error) { switch algo { case RSA: @@ -602,6 +659,43 @@ func parseCertificate(in *certificate) (*Certificate, os.Error) { // If we didn't parse any of the names then we // fall through to the critical check below. + case 30: + // RFC 5280, 4.2.1.10 + + // NameConstraints ::= SEQUENCE { + // permittedSubtrees [0] GeneralSubtrees OPTIONAL, + // excludedSubtrees [1] GeneralSubtrees OPTIONAL } + // + // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree + // + // GeneralSubtree ::= SEQUENCE { + // base GeneralName, + // minimum [0] BaseDistance DEFAULT 0, + // maximum [1] BaseDistance OPTIONAL } + // + // BaseDistance ::= INTEGER (0..MAX) + + var constraints nameConstraints + _, err := asn1.Unmarshal(e.Value, &constraints) + if err != nil { + return nil, err + } + + if len(constraints.Excluded) > 0 && e.Critical { + return out, UnhandledCriticalExtension{} + } + + for _, subtree := range constraints.Permitted { + if subtree.Min > 0 || subtree.Max > 0 || len(subtree.Name) == 0 { + if e.Critical { + return out, UnhandledCriticalExtension{} + } + continue + } + out.PermittedDNSDomains = append(out.PermittedDNSDomains, subtree.Name) + } + continue + case 35: // RFC 5280, 4.2.1.1 var a authKeyId @@ -612,6 +706,44 @@ func parseCertificate(in *certificate) (*Certificate, os.Error) { out.AuthorityKeyId = a.Id continue + case 37: + // RFC 5280, 4.2.1.12. Extended Key Usage + + // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } + // + // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + // + // KeyPurposeId ::= OBJECT IDENTIFIER + + var keyUsage []asn1.ObjectIdentifier + _, err = asn1.Unmarshal(e.Value, &keyUsage) + if err != nil { + return nil, err + } + + for _, u := range keyUsage { + switch { + case u.Equal(oidExtKeyUsageAny): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageAny) + case u.Equal(oidExtKeyUsageServerAuth): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageServerAuth) + case u.Equal(oidExtKeyUsageClientAuth): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageClientAuth) + case u.Equal(oidExtKeyUsageCodeSigning): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageCodeSigning) + case u.Equal(oidExtKeyUsageEmailProtection): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageEmailProtection) + case u.Equal(oidExtKeyUsageTimeStamping): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageTimeStamping) + case u.Equal(oidExtKeyUsageOCSPSigning): + out.ExtKeyUsage = append(out.ExtKeyUsage, ExtKeyUsageOCSPSigning) + default: + out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u) + } + } + + continue + case 14: // RFC 5280, 4.2.1.2 var keyid []byte @@ -698,10 +830,11 @@ var ( oidExtensionBasicConstraints = []int{2, 5, 29, 19} oidExtensionSubjectAltName = []int{2, 5, 29, 17} oidExtensionCertificatePolicies = []int{2, 5, 29, 32} + oidExtensionNameConstraints = []int{2, 5, 29, 30} ) func buildExtensions(template *Certificate) (ret []extension, err os.Error) { - ret = make([]extension, 6 /* maximum number of elements. */ ) + ret = make([]extension, 7 /* maximum number of elements. */ ) n := 0 if template.KeyUsage != 0 { @@ -778,6 +911,22 @@ func buildExtensions(template *Certificate) (ret []extension, err os.Error) { n++ } + if len(template.PermittedDNSDomains) > 0 { + ret[n].Id = oidExtensionNameConstraints + ret[n].Critical = template.PermittedDNSDomainsCritical + + var out nameConstraints + out.Permitted = make([]generalSubtree, len(template.PermittedDNSDomains)) + for i, permitted := range template.PermittedDNSDomains { + out.Permitted[i] = generalSubtree{Name: permitted} + } + ret[n].Value, err = asn1.Marshal(out) + if err != nil { + return + } + n++ + } + // Adding another extension here? Remember to update the maximum number // of elements in the make() at the top of the function. @@ -792,7 +941,8 @@ var ( // CreateSelfSignedCertificate creates a new certificate based on // a template. The following members of template are used: SerialNumber, // Subject, NotBefore, NotAfter, KeyUsage, BasicConstraintsValid, IsCA, -// MaxPathLen, SubjectKeyId, DNSNames. +// MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical, +// PermittedDNSDomains. // // The certificate is signed by parent. If parent is equal to template then the // certificate is self-signed. The parameter pub is the public key of the @@ -840,7 +990,7 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub *rsa.P h.Write(tbsCertContents) digest := h.Sum() - signature, err := rsa.SignPKCS1v15(rand, priv, rsa.HashSHA1, digest) + signature, err := rsa.SignPKCS1v15(rand, priv, crypto.SHA1, digest) if err != nil { return } |