github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/smime/signeddata.go (about) 1 package smime 2 3 import ( 4 "bytes" 5 "crypto/x509" 6 "crypto/x509/pkix" 7 "encoding/asn1" 8 "errors" 9 "fmt" 10 "math/big" 11 12 "github.com/egonelbre/exp/smime/ber" 13 ) 14 15 const panictodo = false 16 17 type SignedData struct { 18 Version int 19 DigestAlgorithms []pkix.AlgorithmIdentifier 20 21 ContentType asn1.ObjectIdentifier 22 Content []byte 23 24 Certificates []*x509.Certificate 25 CRLs []*pkix.CertificateList 26 27 Signers []*Signer 28 } 29 30 func (s *SignedData) findCertFor(signer *Signer) (*x509.Certificate, error) { 31 for _, cert := range s.Certificates { 32 if signer.Id.Matches(cert) { 33 return cert, nil 34 } 35 } 36 return nil, fmt.Errorf("did not find certificate for signer %v", s) 37 } 38 39 func (s *SignedData) CheckSignature() (err error) { 40 if len(s.Signers) == 0 { 41 return fmt.Errorf("no signature found") 42 } 43 44 for _, signer := range s.Signers { 45 var cert *x509.Certificate 46 if cert, err = s.findCertFor(signer); err != nil { 47 return 48 } 49 50 // check the revocation lists 51 revoked := false 52 for _, crl := range s.CRLs { 53 if revokeerr := cert.CheckCRLSignature(crl); revokeerr != nil { 54 revoked = true 55 } 56 } 57 58 if revoked { 59 if panictodo { 60 panic("TODO: check counter signature") 61 } 62 // return fmt.Errorf("smime: certificate has been revoked") 63 } 64 65 data := s.Content 66 if signer.RawSignedAttributes != nil { 67 var attrvalue []byte 68 if attrvalue, err = findSingleAttribute(signer.SignedAttributes, oidMessageDigest); err != nil { 69 return errors.New("smime: message digest not found") 70 } 71 72 var digest []byte 73 74 // the single message digest attribute should be OCTET STRING 75 if _, err = asn1.Unmarshal(attrvalue, &digest); err != nil { 76 return 77 } 78 79 calculated := data 80 if hash := getDigestHashType(signer.DigestAlgorithm.Algorithm); hash.Available() { 81 h := hash.New() 82 h.Write(data) 83 calculated = h.Sum(nil) 84 } 85 86 if !bytes.Equal(digest, calculated) { 87 return errors.New("smime: message digest does not match content") 88 } 89 90 data = signer.RawSignedAttributes 91 } 92 93 algo := getSignatureAlgorithmFromOID(signer.SignatureAlgorithm.Algorithm) 94 err = cert.CheckSignature(algo, data, signer.Signature) 95 if err != nil { 96 return 97 } 98 } 99 return 100 } 101 102 type Signer struct { 103 Id SignerId 104 105 RawSignedAttributes []byte 106 SignedAttributes []Attribute 107 UnsignedAttributes []Attribute 108 109 DigestAlgorithm pkix.AlgorithmIdentifier 110 SignatureAlgorithm pkix.AlgorithmIdentifier 111 112 Signature []byte 113 } 114 115 // Either IssuerAndSerialNumber or SubjectKeyIdentifier 116 type SignerId interface { 117 Matches(*x509.Certificate) bool 118 } 119 120 type IssuerAndSerialNumber struct { 121 Issuer pkix.Name 122 SerialNumber *big.Int 123 } 124 125 func (sid IssuerAndSerialNumber) Matches(cert *x509.Certificate) bool { 126 if panictodo { 127 panic("issuer comparison") 128 } 129 return (sid.Issuer.CommonName == cert.Issuer.CommonName) && 130 (sid.SerialNumber.Cmp(cert.SerialNumber) == 0) 131 } 132 133 type SubjectKeyIdentifier []byte 134 135 func (sid SubjectKeyIdentifier) Matches(cert *x509.Certificate) bool { 136 return bytes.Equal(cert.SubjectKeyId, sid) 137 } 138 139 type Attribute struct { 140 Type asn1.ObjectIdentifier 141 Values [][]byte 142 } 143 144 func findSingleAttribute(attributes []Attribute, oid asn1.ObjectIdentifier) ([]byte, error) { 145 for _, attr := range attributes { 146 if attr.Type.Equal(oid) { 147 if len(attr.Values) != 1 { 148 return nil, errors.New("smime: attribute had improper amount of values") 149 } 150 return attr.Values[0], nil 151 } 152 } 153 return nil, errors.New("smime: did not find required attribute") 154 } 155 156 func convertAttributeSet(attrs asnAttributeSet) (ret []Attribute) { 157 for _, attr := range attrs.Attrs { 158 a := Attribute{attr.Type, nil} 159 for _, val := range attr.Values { 160 data, _ := ber.EncodeTree(val) 161 a.Values = append(a.Values, data) 162 } 163 ret = append(ret, a) 164 } 165 return 166 } 167 168 /* 169 SignedData ::= SEQUENCE { 170 version CMSVersion, 171 digestAlgorithms DigestAlgorithmIdentifiers, 172 encapContentInfo EncapsulatedContentInfo, 173 certificates [0] IMPLICIT CertificateSet OPTIONAL, 174 crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, 175 signerInfos SignerInfos } 176 177 SignerInfos ::= SET OF SignerInfo 178 */ 179 type asnSignedData struct { 180 Version int64 181 Algorithms asnDigestAlgorithms 182 EncapContent asnEncapsulatedContentInfo 183 Certificates asnCertificateSet 184 Crls asnRevocationInfoChoices 185 SignerInfos asnSignerInfos 186 } 187 188 type crl struct{} 189 190 func (d *asnSignedData) marshaler() ber.Marshaler { 191 return ber.Sequence{ 192 ber.Check{ber.Universal, ber.TagInteger, ber.Int64{&d.Version}}, 193 ber.Check{ber.Universal, ber.TagSet, &d.Algorithms}, 194 ber.Check{ber.Universal, ber.TagSequence, &d.EncapContent}, 195 ber.Optional{ber.Check{ber.Context, 0, &d.Certificates}}, 196 ber.Optional{ber.Check{ber.Context, 1, &d.Crls}}, 197 ber.Check{ber.Universal, ber.TagSet, &d.SignerInfos}, 198 } 199 } 200 201 func (d *asnSignedData) Unmarshal(tree *ber.Tree) error { 202 return d.marshaler().Unmarshal(tree) 203 } 204 205 func (d *asnSignedData) Marshal() (*ber.Tree, error) { 206 return d.marshaler().Marshal() 207 } 208 209 func parseSignedData(tree *ber.Tree) (*SignedData, error) { 210 var data asnSignedData 211 err := data.Unmarshal(tree) 212 if err != nil { 213 return nil, err 214 } 215 216 signeddata := &SignedData{ 217 Version: int(data.Version), 218 DigestAlgorithms: data.Algorithms, 219 220 ContentType: data.EncapContent.ContentType, 221 Content: data.EncapContent.Data, 222 223 Certificates: data.Certificates, 224 CRLs: data.Crls, 225 } 226 227 for _, si := range data.SignerInfos { 228 var sid SignerId 229 if si.Issuer.SerialNumber != nil { 230 sid = IssuerAndSerialNumber{si.Issuer.Issuer, si.Issuer.SerialNumber} 231 } else { 232 sid = SubjectKeyIdentifier(si.SubjectKeyId) 233 } 234 235 signer := &Signer{ 236 Id: sid, 237 238 RawSignedAttributes: si.SignedAttrs.Raw, 239 SignedAttributes: convertAttributeSet(si.SignedAttrs), 240 UnsignedAttributes: convertAttributeSet(si.UnsignedAttrs), 241 242 DigestAlgorithm: si.DigestAlgorithm, 243 SignatureAlgorithm: si.SignatureAlgorithm, 244 Signature: si.Signature, 245 } 246 signeddata.Signers = append(signeddata.Signers, signer) 247 } 248 249 return signeddata, nil 250 } 251 252 /* 253 EncapsulatedContentInfo ::= SEQUENCE { 254 eContentType ContentType, 255 eContent [0] EXPLICIT OCTET STRING OPTIONAL } 256 257 ContentType ::= OBJECT IDENTIFIER 258 */ 259 type asnEncapsulatedContentInfo struct { 260 ContentType asn1.ObjectIdentifier 261 Data []byte 262 } 263 264 func (d *asnEncapsulatedContentInfo) marshaler() ber.Marshaler { 265 return ber.Sequence{ 266 ber.Check{ber.Universal, ber.TagObjectIdentifier, ber.ObjectIdentifier{&d.ContentType}}, 267 ber.Optional{ber.Check{ber.Context, 0, 268 ber.Explicit{ 269 ber.Check{ber.Universal, ber.TagOctetString, ber.OctetString{&d.Data}}, 270 }, 271 }}, 272 } 273 } 274 275 func (d *asnEncapsulatedContentInfo) Unmarshal(tree *ber.Tree) error { 276 return d.marshaler().Unmarshal(tree) 277 } 278 279 func (d *asnEncapsulatedContentInfo) Marshal() (*ber.Tree, error) { 280 return d.marshaler().Marshal() 281 } 282 283 /* 284 DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier 285 DigestAlgorithmIdentifier ::= AlgorithmIdentifier 286 */ 287 type asnDigestAlgorithms []pkix.AlgorithmIdentifier 288 289 func (d *asnDigestAlgorithms) Unmarshal(tree *ber.Tree) (err error) { 290 algorithms := make([]pkix.AlgorithmIdentifier, len(tree.Children)) 291 292 for i, child := range tree.Children { 293 id := (*asnAlgorithmIdentifier)(&algorithms[i]) 294 if err = id.Unmarshal(child); err != nil { 295 return 296 } 297 } 298 *d = algorithms 299 return 300 } 301 302 func (d *asnDigestAlgorithms) Marshal() (tree *ber.Tree, err error) { 303 if tree, err = ber.ASN1Tree(d); err != nil { 304 return 305 } 306 tree.Tag = ber.TagSet 307 return tree, err 308 } 309 310 /* 311 AlgorithmIdentifier ::= SEQUENCE { 312 algorithm OBJECT IDENTIFIER, 313 parameters ANY 314 } 315 */ 316 type asnAlgorithmIdentifier pkix.AlgorithmIdentifier 317 318 func (d *asnAlgorithmIdentifier) Unmarshal(tree *ber.Tree) error { 319 return ber.Sequence{ 320 ber.Check{ber.Universal, ber.TagObjectIdentifier, ber.ObjectIdentifier{&d.Algorithm}}, 321 ber.Optional{ber.ASN1RawValue{&d.Parameters}}, 322 }.Unmarshal(tree) 323 } 324 325 func (d *asnAlgorithmIdentifier) Marshal() (*ber.Tree, error) { 326 panic("unimplemented") 327 return nil, nil 328 } 329 330 /* 331 CertificateSet ::= SET OF CertificateChoices 332 CertificateChoices ::= CHOICE { 333 certificate Certificate, 334 extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete 335 v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete 336 v2AttrCert [2] IMPLICIT AttributeCertificateV2, 337 other [3] IMPLICIT OtherCertificateFormat 338 } 339 AttributeCertificateV2 ::= SET OF AttributeCertificate 340 OtherCertificateFormat ::= SEQUENCE { 341 otherCertFormat OBJECT IDENTIFIER, 342 otherCert ANY DEFINED BY otherCertFormat 343 } 344 */ 345 type asnCertificateSet []*x509.Certificate 346 347 func (d *asnCertificateSet) Unmarshal(tree *ber.Tree) (err error) { 348 var cert *x509.Certificate 349 var bytes []byte 350 351 ret := make([]*x509.Certificate, 0, len(tree.Children)) 352 353 for _, child := range tree.Children { 354 if bytes, err = ber.EncodeTree(child); err != nil { 355 return 356 } 357 if cert, err = x509.ParseCertificate(bytes); err != nil { 358 return 359 } 360 ret = append(ret, cert) 361 } 362 *d = ret 363 return 364 } 365 366 func (d *asnCertificateSet) Marshal() (tree *ber.Tree, err error) { 367 tree = &ber.Tree{ 368 Token: &ber.Token{ 369 Kind: ber.Constructed, 370 Class: ber.Universal, 371 Tag: ber.TagSet, 372 }, 373 } 374 375 var sub *ber.Tree 376 for _, cert := range *d { 377 if sub, err = ber.DecodeTree(cert.Raw); err != nil { 378 return nil, err 379 } 380 tree.Children = append(tree.Children, sub) 381 } 382 return 383 } 384 385 /* 386 RevocationInfoChoices ::= SET OF RevocationInfoChoice 387 388 RevocationInfoChoice ::= CHOICE { 389 crl CertificateList, 390 other [1] IMPLICIT OtherRevocationInfoFormat } 391 392 OtherRevocationInfoFormat ::= SEQUENCE { 393 otherRevInfoFormat OBJECT IDENTIFIER, 394 otherRevInfo ANY DEFINED BY otherRevInfoFormat } 395 */ 396 type asnRevocationInfoChoices []*pkix.CertificateList 397 398 func (d *asnRevocationInfoChoices) Unmarshal(tree *ber.Tree) (err error) { 399 var crl *pkix.CertificateList 400 var bytes []byte 401 402 ret := make([]*pkix.CertificateList, 0, len(tree.Children)) 403 for _, child := range tree.Children { 404 if bytes, err = ber.EncodeTree(child); err != nil { 405 return 406 } 407 408 if crl, err = x509.ParseCRL(bytes); err != nil { 409 return 410 } 411 ret = append(ret, crl) 412 } 413 *d = ret 414 return 415 } 416 417 func (d *asnRevocationInfoChoices) Marshal() (tree *ber.Tree, err error) { 418 return ber.ASN1Tree(*d) 419 } 420 421 /* 422 SignerInfos ::= SET OF SignerInfo 423 */ 424 type asnSignerInfos []*asnSignerInfo 425 426 func (d *asnSignerInfos) Unmarshal(tree *ber.Tree) (err error) { 427 ret := make([]*asnSignerInfo, len(tree.Children)) 428 for i, child := range tree.Children { 429 v := &asnSignerInfo{} 430 if err = v.Unmarshal(child); err != nil { 431 return 432 } 433 ret[i] = v 434 } 435 *d = ret 436 return 437 } 438 439 func (d *asnSignerInfos) Marshal() (tree *ber.Tree, err error) { 440 tree = &ber.Tree{ 441 Token: &ber.Token{ 442 Kind: ber.Constructed, 443 Class: ber.Universal, 444 Tag: ber.TagSet, 445 }, 446 } 447 448 var sub *ber.Tree 449 for _, info := range *d { 450 if sub, err = info.Marshal(); err != nil { 451 return 452 } 453 tree.Children = append(tree.Children, sub) 454 } 455 456 return 457 } 458 459 /* 460 461 SignerInfo ::= SEQUENCE { 462 version CMSVersion, 463 sid SignerIdentifier, 464 digestAlgorithm DigestAlgorithmIdentifier, 465 signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, 466 signatureAlgorithm SignatureAlgorithmIdentifier, 467 signature SignatureValue, 468 unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } 469 470 SignerIdentifier ::= CHOICE { 471 issuerAndSerialNumber IssuerAndSerialNumber, 472 subjectKeyIdentifier [0] SubjectKeyIdentifier } 473 474 SignatureValue ::= OCTET STRING 475 */ 476 type asnSignerInfo struct { 477 Version int64 478 Issuer asnIssuerAndSerialNumber 479 SubjectKeyId []byte 480 DigestAlgorithm pkix.AlgorithmIdentifier 481 SignedAttrs asnAttributeSet 482 SignatureAlgorithm pkix.AlgorithmIdentifier 483 Signature []byte 484 UnsignedAttrs asnAttributeSet 485 } 486 487 func (d *asnSignerInfo) marshaler() ber.Marshaler { 488 return ber.Sequence{ 489 ber.Check{ber.Universal, ber.TagInteger, ber.Int64{&d.Version}}, 490 ber.Choice{ 491 ber.Check{ber.Universal, ber.TagSequence, &d.Issuer}, 492 ber.Check{ber.Context, 0, ber.OctetString{&d.SubjectKeyId}}, 493 }, 494 ber.Check{ber.Universal, ber.TagSequence, (*asnAlgorithmIdentifier)(&d.DigestAlgorithm)}, 495 ber.Optional{ber.Check{ber.Context, 0, &d.SignedAttrs}}, 496 ber.Check{ber.Universal, ber.TagSequence, (*asnAlgorithmIdentifier)(&d.SignatureAlgorithm)}, 497 ber.Check{ber.Universal, ber.TagOctetString, ber.OctetString{&d.Signature}}, 498 ber.Optional{ber.Check{ber.Context, 1, &d.UnsignedAttrs}}, 499 } 500 } 501 502 func (d *asnSignerInfo) Unmarshal(tree *ber.Tree) error { 503 return d.marshaler().Unmarshal(tree) 504 } 505 506 func (d *asnSignerInfo) Marshal() (*ber.Tree, error) { 507 return d.marshaler().Marshal() 508 } 509 510 /* 511 IssuerAndSerialNumber ::= SEQUENCE { 512 issuer Name, 513 serialNumber CertificateSerialNumber } 514 515 CertificateSerialNumber ::= INTEGER 516 */ 517 type asnIssuerAndSerialNumber struct { 518 Issuer pkix.Name 519 SerialNumber *big.Int 520 } 521 522 func (d *asnIssuerAndSerialNumber) marshaler() ber.Marshaler { 523 return ber.Sequence{ 524 ber.Check{ber.Universal, ber.TagSequence, (*asnName)(&d.Issuer)}, 525 ber.Check{ber.Universal, ber.TagInteger, ber.BigInt{&d.SerialNumber}}, 526 } 527 } 528 529 func (d *asnIssuerAndSerialNumber) Unmarshal(tree *ber.Tree) (err error) { 530 return d.marshaler().Unmarshal(tree) 531 } 532 533 func (d *asnIssuerAndSerialNumber) Marshal() (*ber.Tree, error) { 534 return d.marshaler().Marshal() 535 } 536 537 type asnName pkix.Name 538 539 func (d *asnName) Unmarshal(tree *ber.Tree) (err error) { 540 var bytes []byte 541 if bytes, err = ber.EncodeTree(tree); err != nil { 542 return 543 } 544 545 var rdns pkix.RDNSequence 546 if _, err = asn1.Unmarshal(bytes, &rdns); err != nil { 547 return 548 } 549 (*pkix.Name)(d).FillFromRDNSequence(&rdns) 550 551 return 552 } 553 554 func (d *asnName) Marshal() (*ber.Tree, error) { 555 panic("unimplemented") 556 return nil, nil 557 } 558 559 type asnAttributeSet struct { 560 Raw []byte 561 Attrs []asnAttribute 562 } 563 564 func (d *asnAttributeSet) Unmarshal(tree *ber.Tree) (err error) { 565 ret := make([]asnAttribute, len(tree.Children)) 566 for i, child := range tree.Children { 567 err = (&ret[i]).Unmarshal(child) 568 if err != nil { 569 return 570 } 571 } 572 573 d.Attrs = ret 574 temp := &ber.Tree{ 575 Token: &ber.Token{ 576 Kind: ber.Constructed, 577 Class: ber.Universal, 578 Tag: ber.TagSet, 579 }, 580 Children: tree.Children, 581 } 582 d.Raw, err = ber.EncodeTree(temp) 583 return 584 } 585 586 func (d *asnAttributeSet) Marshal() (*ber.Tree, error) { 587 panic("unimplemented") 588 return nil, nil 589 } 590 591 type asnAttribute struct { 592 Type asn1.ObjectIdentifier 593 Values []*ber.Tree 594 } 595 596 func (d *asnAttribute) Unmarshal(tree *ber.Tree) (err error) { 597 var temp *ber.Tree 598 599 err = ber.Sequence{ 600 ber.Check{ber.Universal, ber.TagObjectIdentifier, ber.ObjectIdentifier{&d.Type}}, 601 ber.Check{ber.Universal, ber.TagSet, ber.RawTree{&temp}}, 602 }.Unmarshal(tree) 603 604 if err != nil { 605 return 606 } 607 608 d.Values = temp.Children 609 return 610 } 611 612 func (d *asnAttribute) Marshal() (*ber.Tree, error) { 613 panic("unimplemented") 614 return nil, nil 615 }