| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Go Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style | |
| 3 // license that can be found in the LICENSE file. | |
| 4 | |
| 5 package main | |
| 6 | |
| 7 import ( | |
| 8 "crypto" | |
| 9 "crypto/rsa" | |
| 10 "crypto/sha1" | |
| 11 "crypto/x509" | |
| 12 "crypto/x509/pkix" | |
| 13 "encoding/asn1" | |
| 14 "io" | |
| 15 "math/big" | |
| 16 "time" | |
| 17 ) | |
| 18 | |
| 19 // signPKCS7 does the minimal amount of work necessary to embed an RSA | |
| 20 // signature into a PKCS#7 certificate. | |
| 21 // | |
| 22 // We prepare the certificate using the x509 package, read it back in | |
| 23 // to our custom data type and then write it back out with the signature. | |
| 24 func signPKCS7(rand io.Reader, priv *rsa.PrivateKey, msg []byte) ([]byte, error)
{ | |
| 25 const serialNumber = 0x5462c4dd // arbitrary | |
| 26 name := pkix.Name{CommonName: "gomobile"} | |
| 27 | |
| 28 template := &x509.Certificate{ | |
| 29 SerialNumber: big.NewInt(serialNumber), | |
| 30 SignatureAlgorithm: x509.SHA1WithRSA, | |
| 31 Subject: name, | |
| 32 } | |
| 33 | |
| 34 b, err := x509.CreateCertificate(rand, template, template, priv.Public()
, priv) | |
| 35 if err != nil { | |
| 36 return nil, err | |
| 37 } | |
| 38 | |
| 39 c := certificate{} | |
| 40 if _, err := asn1.Unmarshal(b, &c); err != nil { | |
| 41 return nil, err | |
| 42 } | |
| 43 | |
| 44 h := sha1.New() | |
| 45 h.Write(msg) | |
| 46 hashed := h.Sum(nil) | |
| 47 | |
| 48 signed, err := rsa.SignPKCS1v15(rand, priv, crypto.SHA1, hashed) | |
| 49 if err != nil { | |
| 50 return nil, err | |
| 51 } | |
| 52 | |
| 53 content := pkcs7SignedData{ | |
| 54 ContentType: oidSignedData, | |
| 55 Content: signedData{ | |
| 56 Version: 1, | |
| 57 DigestAlgorithms: []pkix.AlgorithmIdentifier{{ | |
| 58 Algorithm: oidSHA1, | |
| 59 Parameters: asn1.RawValue{Tag: 5}, | |
| 60 }}, | |
| 61 ContentInfo: contentInfo{Type: oidData}, | |
| 62 Certificates: c, | |
| 63 SignerInfos: []signerInfo{{ | |
| 64 Version: 1, | |
| 65 IssuerAndSerialNumber: issuerAndSerialNumber{ | |
| 66 Issuer: name.ToRDNSequence(), | |
| 67 SerialNumber: serialNumber, | |
| 68 }, | |
| 69 DigestAlgorithm: pkix.AlgorithmIdentifier{ | |
| 70 Algorithm: oidSHA1, | |
| 71 Parameters: asn1.RawValue{Tag: 5}, | |
| 72 }, | |
| 73 DigestEncryptionAlgorithm: pkix.AlgorithmIdentif
ier{ | |
| 74 Algorithm: oidRSAEncryption, | |
| 75 Parameters: asn1.RawValue{Tag: 5}, | |
| 76 }, | |
| 77 EncryptedDigest: signed, | |
| 78 }}, | |
| 79 }, | |
| 80 } | |
| 81 | |
| 82 return asn1.Marshal(content) | |
| 83 } | |
| 84 | |
| 85 type pkcs7SignedData struct { | |
| 86 ContentType asn1.ObjectIdentifier | |
| 87 Content signedData `asn1:"tag:0,explicit"` | |
| 88 } | |
| 89 | |
| 90 // signedData is defined in rfc2315, section 9.1. | |
| 91 type signedData struct { | |
| 92 Version int | |
| 93 DigestAlgorithms []pkix.AlgorithmIdentifier `asn1:"set"` | |
| 94 ContentInfo contentInfo | |
| 95 Certificates certificate `asn1:"tag0,explicit"` | |
| 96 SignerInfos []signerInfo `asn1:"set"` | |
| 97 } | |
| 98 | |
| 99 type contentInfo struct { | |
| 100 Type asn1.ObjectIdentifier | |
| 101 // Content is optional in PKCS#7 and not provided here. | |
| 102 } | |
| 103 | |
| 104 // certificate is defined in rfc2459, section 4.1. | |
| 105 type certificate struct { | |
| 106 TBSCertificate tbsCertificate | |
| 107 SignatureAlgorithm pkix.AlgorithmIdentifier | |
| 108 SignatureValue asn1.BitString | |
| 109 } | |
| 110 | |
| 111 // tbsCertificate is defined in rfc2459, section 4.1. | |
| 112 type tbsCertificate struct { | |
| 113 Version int `asn1:"tag:0,default:2,explicit"` | |
| 114 SerialNumber int | |
| 115 Signature pkix.AlgorithmIdentifier | |
| 116 Issuer pkix.RDNSequence // pkix.Name | |
| 117 Validity validity | |
| 118 Subject pkix.RDNSequence // pkix.Name | |
| 119 SubjectPKI subjectPublicKeyInfo | |
| 120 } | |
| 121 | |
| 122 // validity is defined in rfc2459, section 4.1. | |
| 123 type validity struct { | |
| 124 NotBefore time.Time | |
| 125 NotAfter time.Time | |
| 126 } | |
| 127 | |
| 128 // subjectPublicKeyInfo is defined in rfc2459, section 4.1. | |
| 129 type subjectPublicKeyInfo struct { | |
| 130 Algorithm pkix.AlgorithmIdentifier | |
| 131 SubjectPublicKey asn1.BitString | |
| 132 } | |
| 133 | |
| 134 type signerInfo struct { | |
| 135 Version int | |
| 136 IssuerAndSerialNumber issuerAndSerialNumber | |
| 137 DigestAlgorithm pkix.AlgorithmIdentifier | |
| 138 DigestEncryptionAlgorithm pkix.AlgorithmIdentifier | |
| 139 EncryptedDigest []byte | |
| 140 } | |
| 141 | |
| 142 type issuerAndSerialNumber struct { | |
| 143 Issuer pkix.RDNSequence // pkix.Name | |
| 144 SerialNumber int | |
| 145 } | |
| 146 | |
| 147 // Various ASN.1 Object Identifies, mostly from rfc3852. | |
| 148 var ( | |
| 149 oidPKCS7 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7} | |
| 150 oidData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1} | |
| 151 oidSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2} | |
| 152 oidSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} | |
| 153 oidRSAEncryption = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} | |
| 154 ) | |
| OLD | NEW |