1 package pkcs7
2
3 import (
4 "bytes"
5 "crypto"
6 "crypto/dsa"
7 "crypto/ed25519"
8 "crypto/rand"
9 "crypto/x509"
10 "crypto/x509/pkix"
11 "encoding/asn1"
12 "errors"
13 "fmt"
14 "math/big"
15 "time"
16 )
17
18
19 type SignedData struct {
20 sd signedData
21 certs []*x509.Certificate
22 data, messageDigest []byte
23 digestOid asn1.ObjectIdentifier
24 encryptionOid asn1.ObjectIdentifier
25 }
26
27
28
29
30 func NewSignedData(data []byte) (*SignedData, error) {
31 content, err := asn1.Marshal(data)
32 if err != nil {
33 return nil, err
34 }
35 ci := contentInfo{
36 ContentType: OIDData,
37 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
38 }
39 sd := signedData{
40 ContentInfo: ci,
41 Version: 1,
42 }
43 return &SignedData{sd: sd, data: data, digestOid: OIDDigestAlgorithmSHA1}, nil
44 }
45
46
47 type SignerInfoConfig struct {
48 ExtraSignedAttributes []Attribute
49 ExtraUnsignedAttributes []Attribute
50 SkipCertificates bool
51 }
52
53 type signedData struct {
54 Version int `asn1:"default:1"`
55 DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
56 ContentInfo contentInfo
57 Certificates rawCertificates `asn1:"optional,tag:0"`
58 CRLs []pkix.CertificateList `asn1:"optional,tag:1"`
59 SignerInfos []signerInfo `asn1:"set"`
60 }
61
62 type signerInfo struct {
63 Version int `asn1:"default:1"`
64 IssuerAndSerialNumber issuerAndSerial
65 DigestAlgorithm pkix.AlgorithmIdentifier
66 AuthenticatedAttributes []attribute `asn1:"optional,omitempty,tag:0"`
67 DigestEncryptionAlgorithm pkix.AlgorithmIdentifier
68 EncryptedDigest []byte
69 UnauthenticatedAttributes []attribute `asn1:"optional,omitempty,tag:1"`
70 }
71
72 type attribute struct {
73 Type asn1.ObjectIdentifier
74 Value asn1.RawValue `asn1:"set"`
75 }
76
77 func marshalAttributes(attrs []attribute) ([]byte, error) {
78 encodedAttributes, err := asn1.Marshal(struct {
79 A []attribute `asn1:"set"`
80 }{A: attrs})
81 if err != nil {
82 return nil, err
83 }
84
85
86 var raw asn1.RawValue
87 asn1.Unmarshal(encodedAttributes, &raw)
88 return raw.Bytes, nil
89 }
90
91 type rawCertificates struct {
92 Raw asn1.RawContent
93 }
94
95 type issuerAndSerial struct {
96 IssuerName asn1.RawValue
97 SerialNumber *big.Int
98 }
99
100
101
102
103 func (sd *SignedData) SetDigestAlgorithm(d asn1.ObjectIdentifier) {
104 sd.digestOid = d
105 }
106
107
108
109
110 func (sd *SignedData) SetEncryptionAlgorithm(d asn1.ObjectIdentifier) {
111 sd.encryptionOid = d
112 }
113
114
115
116 func (sd *SignedData) AddSigner(ee *x509.Certificate, keyOrSigner interface{}, config SignerInfoConfig) error {
117 var parents []*x509.Certificate
118 return sd.AddSignerChain(ee, keyOrSigner, parents, config)
119 }
120
121
122
123
124
125
126
127
128
129 func (sd *SignedData) AddSignerChain(ee *x509.Certificate, keyOrSigner interface{}, parents []*x509.Certificate, config SignerInfoConfig) error {
130
131
132
133
134 var ias issuerAndSerial
135 ias.SerialNumber = ee.SerialNumber
136 if len(parents) == 0 {
137
138 ias.IssuerName = asn1.RawValue{FullBytes: ee.RawIssuer}
139 } else {
140 err := verifyPartialChain(ee, parents)
141 if err != nil {
142 return err
143 }
144
145 ias.IssuerName = asn1.RawValue{FullBytes: parents[0].RawSubject}
146 }
147 sd.sd.DigestAlgorithmIdentifiers = append(sd.sd.DigestAlgorithmIdentifiers,
148 pkix.AlgorithmIdentifier{Algorithm: sd.digestOid},
149 )
150 hash, err := getHashForOID(sd.digestOid)
151 if err != nil {
152 return err
153 }
154 h := hash.New()
155 h.Write(sd.data)
156 sd.messageDigest = h.Sum(nil)
157 encryptionOid, err := getOIDForEncryptionAlgorithm(keyOrSigner, sd.digestOid)
158 if err != nil {
159 return err
160 }
161 attrs := &attributes{}
162 attrs.Add(OIDAttributeContentType, sd.sd.ContentInfo.ContentType)
163 attrs.Add(OIDAttributeMessageDigest, sd.messageDigest)
164 attrs.Add(OIDAttributeSigningTime, time.Now().UTC())
165 for _, attr := range config.ExtraSignedAttributes {
166 attrs.Add(attr.Type, attr.Value)
167 }
168 finalAttrs, err := attrs.ForMarshalling()
169 if err != nil {
170 return err
171 }
172 unsignedAttrs := &attributes{}
173 for _, attr := range config.ExtraUnsignedAttributes {
174 unsignedAttrs.Add(attr.Type, attr.Value)
175 }
176 finalUnsignedAttrs, err := unsignedAttrs.ForMarshalling()
177 if err != nil {
178 return err
179 }
180
181 signature, err := signAttributes(finalAttrs, keyOrSigner, hash)
182 if err != nil {
183 return err
184 }
185 signerInfo := signerInfo{
186 AuthenticatedAttributes: finalAttrs,
187 UnauthenticatedAttributes: finalUnsignedAttrs,
188 DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.digestOid},
189 DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: encryptionOid},
190 IssuerAndSerialNumber: ias,
191 EncryptedDigest: signature,
192 Version: 1,
193 }
194 if !config.SkipCertificates {
195 sd.certs = append(sd.certs, ee)
196 if len(parents) > 0 {
197 sd.certs = append(sd.certs, parents...)
198 }
199 }
200 sd.sd.SignerInfos = append(sd.sd.SignerInfos, signerInfo)
201 return nil
202 }
203
204
205
206
207
208
209
210
211 func (sd *SignedData) SignWithoutAttr(ee *x509.Certificate, keyOrSigner interface{}, config SignerInfoConfig) error {
212 var signature []byte
213 sd.sd.DigestAlgorithmIdentifiers = append(sd.sd.DigestAlgorithmIdentifiers, pkix.AlgorithmIdentifier{Algorithm: sd.digestOid})
214 hash, err := getHashForOID(sd.digestOid)
215 if err != nil {
216 return err
217 }
218 h := hash.New()
219 h.Write(sd.data)
220 sd.messageDigest = h.Sum(nil)
221
222 switch pkey := keyOrSigner.(type) {
223 case *dsa.PrivateKey:
224
225
226 r, s, err := dsa.Sign(rand.Reader, pkey, sd.messageDigest)
227 if err != nil {
228 return err
229 }
230 signature, err = asn1.Marshal(dsaSignature{r, s})
231 if err != nil {
232 return err
233 }
234 default:
235 signer, ok := keyOrSigner.(crypto.Signer)
236 if !ok {
237 return errors.New("pkcs7: private key does not implement crypto.Signer")
238 }
239
240
241 _, ok = signer.Public().(ed25519.PublicKey)
242 if ok {
243 signature, err = signer.Sign(rand.Reader, sd.data, crypto.Hash(0))
244 } else {
245 signature, err = signer.Sign(rand.Reader, sd.messageDigest, hash)
246 if err != nil {
247 return err
248 }
249 }
250 }
251
252 var ias issuerAndSerial
253 ias.SerialNumber = ee.SerialNumber
254
255 ias.IssuerName = asn1.RawValue{FullBytes: ee.RawIssuer}
256 if sd.encryptionOid == nil {
257
258
259 sd.encryptionOid, err = getOIDForEncryptionAlgorithm(keyOrSigner, sd.digestOid)
260 }
261 if err != nil {
262 return err
263 }
264 signerInfo := signerInfo{
265 DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.digestOid},
266 DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: sd.encryptionOid},
267 IssuerAndSerialNumber: ias,
268 EncryptedDigest: signature,
269 Version: 1,
270 }
271
272 sd.certs = append(sd.certs, ee)
273 sd.sd.SignerInfos = append(sd.sd.SignerInfos, signerInfo)
274 return nil
275 }
276
277 func (si *signerInfo) SetUnauthenticatedAttributes(extraUnsignedAttrs []Attribute) error {
278 unsignedAttrs := &attributes{}
279 for _, attr := range extraUnsignedAttrs {
280 unsignedAttrs.Add(attr.Type, attr.Value)
281 }
282 finalUnsignedAttrs, err := unsignedAttrs.ForMarshalling()
283 if err != nil {
284 return err
285 }
286
287 si.UnauthenticatedAttributes = finalUnsignedAttrs
288
289 return nil
290 }
291
292
293 func (sd *SignedData) AddCertificate(cert *x509.Certificate) {
294 sd.certs = append(sd.certs, cert)
295 }
296
297
298
299 func (sd *SignedData) SetContentType(contentType asn1.ObjectIdentifier) {
300 sd.sd.ContentInfo.ContentType = contentType
301 }
302
303
304
305 func (sd *SignedData) Detach() {
306 sd.sd.ContentInfo = contentInfo{ContentType: OIDData}
307 }
308
309
310 func (sd *SignedData) GetSignedData() *signedData {
311 return &sd.sd
312 }
313
314
315 func (sd *SignedData) Finish() ([]byte, error) {
316 sd.sd.Certificates = marshalCertificates(sd.certs)
317 inner, err := asn1.Marshal(sd.sd)
318 if err != nil {
319 return nil, err
320 }
321 outer := contentInfo{
322 ContentType: OIDSignedData,
323 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: inner, IsCompound: true},
324 }
325 return asn1.Marshal(outer)
326 }
327
328
329
330 func (sd *SignedData) RemoveAuthenticatedAttributes() {
331 for i := range sd.sd.SignerInfos {
332 sd.sd.SignerInfos[i].AuthenticatedAttributes = nil
333 }
334 }
335
336
337 func (sd *SignedData) RemoveUnauthenticatedAttributes() {
338 for i := range sd.sd.SignerInfos {
339 sd.sd.SignerInfos[i].UnauthenticatedAttributes = nil
340 }
341 }
342
343
344
345
346
347 func verifyPartialChain(cert *x509.Certificate, parents []*x509.Certificate) error {
348 if len(parents) == 0 {
349 return fmt.Errorf("pkcs7: zero parents provided to verify the signature of certificate %q", cert.Subject.CommonName)
350 }
351 err := cert.CheckSignatureFrom(parents[0])
352 if err != nil {
353 return fmt.Errorf("pkcs7: certificate signature from parent is invalid: %v", err)
354 }
355 if len(parents) == 1 {
356
357 return nil
358 }
359 return verifyPartialChain(parents[0], parents[1:])
360 }
361
362 func cert2issuerAndSerial(cert *x509.Certificate) (issuerAndSerial, error) {
363 var ias issuerAndSerial
364
365
366 ias.IssuerName = asn1.RawValue{FullBytes: cert.RawIssuer}
367 ias.SerialNumber = cert.SerialNumber
368
369 return ias, nil
370 }
371
372
373 func signAttributes(attrs []attribute, keyOrSigner interface{}, digestAlg crypto.Hash) ([]byte, error) {
374 attrBytes, err := marshalAttributes(attrs)
375 if err != nil {
376 return nil, err
377 }
378 h := digestAlg.New()
379 h.Write(attrBytes)
380 hash := h.Sum(nil)
381
382
383
384 switch pkey := keyOrSigner.(type) {
385 case *dsa.PrivateKey:
386 r, s, err := dsa.Sign(rand.Reader, pkey, hash)
387 if err != nil {
388 return nil, err
389 }
390 return asn1.Marshal(dsaSignature{r, s})
391 }
392
393 signer, ok := keyOrSigner.(crypto.Signer)
394 if !ok {
395 return nil, errors.New("pkcs7: private key does not implement crypto.Signer")
396 }
397
398
399 _, ok = signer.Public().(ed25519.PublicKey)
400 if ok {
401 return signer.Sign(rand.Reader, attrBytes, crypto.Hash(0))
402 }
403
404 return signer.Sign(rand.Reader, hash, digestAlg)
405 }
406
407 type dsaSignature struct {
408 R, S *big.Int
409 }
410
411
412 func marshalCertificates(certs []*x509.Certificate) rawCertificates {
413 var buf bytes.Buffer
414 for _, cert := range certs {
415 buf.Write(cert.Raw)
416 }
417 rawCerts, _ := marshalCertificateBytes(buf.Bytes())
418 return rawCerts
419 }
420
421
422
423
424 func marshalCertificateBytes(certs []byte) (rawCertificates, error) {
425 var val = asn1.RawValue{Bytes: certs, Class: 2, Tag: 0, IsCompound: true}
426 b, err := asn1.Marshal(val)
427 if err != nil {
428 return rawCertificates{}, err
429 }
430 return rawCertificates{Raw: b}, nil
431 }
432
433
434
435 func DegenerateCertificate(cert []byte) ([]byte, error) {
436 rawCert, err := marshalCertificateBytes(cert)
437 if err != nil {
438 return nil, err
439 }
440 emptyContent := contentInfo{ContentType: OIDData}
441 sd := signedData{
442 Version: 1,
443 ContentInfo: emptyContent,
444 Certificates: rawCert,
445 CRLs: []pkix.CertificateList{},
446 }
447 content, err := asn1.Marshal(sd)
448 if err != nil {
449 return nil, err
450 }
451 signedContent := contentInfo{
452 ContentType: OIDSignedData,
453 Content: asn1.RawValue{Class: 2, Tag: 0, Bytes: content, IsCompound: true},
454 }
455 return asn1.Marshal(signedContent)
456 }
457
View as plain text