github.com/emmansun/gmsm@v0.29.1/pkcs7/pkcs7.go (about) 1 // Package pkcs7 implements parsing and generation of some PKCS#7 structures. 2 package pkcs7 3 4 import ( 5 "bytes" 6 "crypto" 7 "crypto/dsa" 8 "crypto/ecdsa" 9 "crypto/rsa" 10 "crypto/x509" 11 "crypto/x509/pkix" 12 "encoding/asn1" 13 "errors" 14 "fmt" 15 "sort" 16 17 _ "crypto/sha1" // for crypto.SHA1 18 19 "github.com/emmansun/gmsm/sm2" 20 "github.com/emmansun/gmsm/smx509" 21 ) 22 23 // PKCS7 Represents a PKCS7 structure 24 type PKCS7 struct { 25 Content []byte 26 Certificates []*smx509.Certificate 27 CRLs []pkix.CertificateList 28 Signers []signerInfo 29 raw any 30 } 31 32 type contentInfo struct { 33 ContentType asn1.ObjectIdentifier 34 Content asn1.RawValue `asn1:"explicit,optional,tag:0"` 35 } 36 37 // ErrUnsupportedContentType is returned when a PKCS7 content is not supported. 38 // Currently only Data (1.2.840.113549.1.7.1), Signed Data (1.2.840.113549.1.7.2), 39 // and Enveloped Data are supported (1.2.840.113549.1.7.3) 40 var ErrUnsupportedContentType = errors.New("pkcs7: cannot parse data: unimplemented content type") 41 42 type unsignedData []byte 43 44 var ( 45 // Signed Data OIDs 46 OIDData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 1} 47 OIDSignedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 2} 48 OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 3} 49 OIDSignedEnvelopedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 4} 50 OIDDigestData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 5} 51 OIDEncryptedData = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 7, 6} 52 OIDAttributeContentType = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 3} 53 OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4} 54 OIDAttributeSigningTime = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 5} 55 56 // Digest Algorithms 57 OIDDigestAlgorithmSHA1 = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 26} 58 OIDDigestAlgorithmSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} 59 OIDDigestAlgorithmSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} 60 OIDDigestAlgorithmSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} 61 62 OIDDigestAlgorithmDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1} 63 OIDDigestAlgorithmDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} 64 65 OIDDigestAlgorithmECDSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} 66 OIDDigestAlgorithmECDSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} 67 OIDDigestAlgorithmECDSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} 68 OIDDigestAlgorithmECDSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} 69 70 // Signature Algorithms 71 OIDEncryptionAlgorithmRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} 72 OIDEncryptionAlgorithmRSASHA1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} 73 OIDEncryptionAlgorithmRSASHA256 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} 74 OIDEncryptionAlgorithmRSASHA384 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} 75 OIDEncryptionAlgorithmRSASHA512 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} 76 77 OIDEncryptionAlgorithmECDSAP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} 78 OIDEncryptionAlgorithmECDSAP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} 79 OIDEncryptionAlgorithmECDSAP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} 80 ) 81 82 var ( 83 // SM2 Signed Data OIDs 84 // 《GB/T 35275-2017 信息安全技术 SM2密码算法加密签名消息语法规范》 85 SM2OIDData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 1} 86 SM2OIDSignedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 2} 87 SM2OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 3} 88 SM2OIDSignedEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 4} 89 SM2OIDEncryptedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 2, 5} 90 91 // Digest Algorithms 92 OIDDigestAlgorithmSM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 401} 93 // SM2Sign-with-SM3 94 OIDDigestAlgorithmSM2SM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 501} 95 // Signature Algorithms SM2-1 96 OIDDigestEncryptionAlgorithmSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301, 1} 97 98 // Encryption Algorithms SM2-3 99 OIDKeyEncryptionAlgorithmSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301, 3} 100 101 //SM9 Signed Data OIDs 102 SM9OIDData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 1} 103 SM9OIDSignedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 2} 104 SM9OIDEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 3} 105 SM9OIDSignedEnvelopedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 4} 106 SM9OIDEncryptedData = asn1.ObjectIdentifier{1, 2, 156, 10197, 6, 1, 4, 4, 5} 107 108 // SM9Sign-with-SM3 109 OIDDigestAlgorithmSM9SM3 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 502} 110 111 // Signature Algorithms SM9-1 112 OIDDigestEncryptionAlgorithmSM9 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 1} 113 114 // Encryption Algorithms SM9-3 115 OIDKeyEncryptionAlgorithmSM9 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 302, 3} 116 ) 117 118 func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) { 119 switch { 120 case oid.Equal(OIDDigestAlgorithmSHA1), oid.Equal(OIDDigestAlgorithmECDSASHA1), 121 oid.Equal(OIDDigestAlgorithmDSA), oid.Equal(OIDDigestAlgorithmDSASHA1), 122 oid.Equal(OIDEncryptionAlgorithmRSA): 123 return crypto.SHA1, nil 124 case oid.Equal(OIDDigestAlgorithmSHA256), oid.Equal(OIDDigestAlgorithmECDSASHA256): 125 return crypto.SHA256, nil 126 case oid.Equal(OIDDigestAlgorithmSHA384), oid.Equal(OIDDigestAlgorithmECDSASHA384): 127 return crypto.SHA384, nil 128 case oid.Equal(OIDDigestAlgorithmSHA512), oid.Equal(OIDDigestAlgorithmECDSASHA512): 129 return crypto.SHA512, nil 130 case oid.Equal(OIDDigestAlgorithmSM3), oid.Equal(OIDDigestAlgorithmSM2SM3): 131 return crypto.Hash(0), nil 132 } 133 return crypto.Hash(0), fmt.Errorf("pkcs7: cannot get hash from oid %v", oid) 134 } 135 136 // getDigestOIDForSignatureAlgorithm takes an x509.SignatureAlgorithm 137 // and returns the corresponding OID digest algorithm 138 func getDigestOIDForSignatureAlgorithm(digestAlg x509.SignatureAlgorithm) (asn1.ObjectIdentifier, error) { 139 switch digestAlg { 140 case x509.SHA1WithRSA, x509.ECDSAWithSHA1: 141 return OIDDigestAlgorithmSHA1, nil 142 case x509.SHA256WithRSA, x509.ECDSAWithSHA256: 143 return OIDDigestAlgorithmSHA256, nil 144 case x509.SHA384WithRSA, x509.ECDSAWithSHA384: 145 return OIDDigestAlgorithmSHA384, nil 146 case x509.SHA512WithRSA, x509.ECDSAWithSHA512: 147 return OIDDigestAlgorithmSHA512, nil 148 case smx509.SM2WithSM3: 149 return OIDDigestAlgorithmSM3, nil 150 } 151 return nil, fmt.Errorf("pkcs7: cannot convert hash to oid, unknown hash algorithm") 152 } 153 154 // getOIDForEncryptionAlgorithm takes the public or private key type of the signer and 155 // the OID of a digest algorithm to return the appropriate signerInfo.DigestEncryptionAlgorithm 156 func getOIDForEncryptionAlgorithm(pkey any, OIDDigestAlg asn1.ObjectIdentifier) (asn1.ObjectIdentifier, error) { 157 switch k := pkey.(type) { 158 case *rsa.PrivateKey, *rsa.PublicKey: 159 switch { 160 default: 161 return OIDEncryptionAlgorithmRSA, nil 162 case OIDDigestAlg.Equal(OIDEncryptionAlgorithmRSA): 163 return OIDEncryptionAlgorithmRSA, nil 164 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1): 165 return OIDEncryptionAlgorithmRSASHA1, nil 166 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256): 167 return OIDEncryptionAlgorithmRSASHA256, nil 168 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384): 169 return OIDEncryptionAlgorithmRSASHA384, nil 170 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512): 171 return OIDEncryptionAlgorithmRSASHA512, nil 172 } 173 case *ecdsa.PrivateKey, *ecdsa.PublicKey: 174 switch { 175 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA1): 176 return OIDDigestAlgorithmECDSASHA1, nil 177 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA256): 178 return OIDDigestAlgorithmECDSASHA256, nil 179 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA384): 180 return OIDDigestAlgorithmECDSASHA384, nil 181 case OIDDigestAlg.Equal(OIDDigestAlgorithmSHA512): 182 return OIDDigestAlgorithmECDSASHA512, nil 183 case OIDDigestAlg.Equal(OIDDigestAlgorithmSM3): 184 // Do we need further checking? 185 return OIDDigestEncryptionAlgorithmSM2, nil 186 } 187 case *sm2.PrivateKey: 188 return OIDDigestEncryptionAlgorithmSM2, nil 189 case *dsa.PrivateKey, *dsa.PublicKey: 190 return OIDDigestAlgorithmDSA, nil 191 case crypto.Signer: 192 return getOIDForEncryptionAlgorithm(k.Public(), OIDDigestAlg) 193 } 194 return nil, fmt.Errorf("pkcs7: cannot convert encryption algorithm to oid, unknown or unsupported private key type %T", pkey) 195 196 } 197 198 // Parse decodes a DER encoded PKCS7 package 199 func Parse(data []byte) (p7 *PKCS7, err error) { 200 if len(data) == 0 { 201 return nil, errors.New("pkcs7: input data is empty") 202 } 203 var info contentInfo 204 der, err := ber2der(data) 205 if err != nil { 206 return nil, err 207 } 208 rest, err := asn1.Unmarshal(der, &info) 209 if len(rest) > 0 { 210 err = asn1.SyntaxError{Msg: "trailing data"} 211 return 212 } 213 if err != nil { 214 return 215 } 216 217 switch { 218 case info.ContentType.Equal(OIDSignedData) || info.ContentType.Equal(SM2OIDSignedData): 219 return parseSignedData(info.Content.Bytes) 220 case info.ContentType.Equal(OIDEnvelopedData) || info.ContentType.Equal(SM2OIDEnvelopedData): 221 return parseEnvelopedData(info.Content.Bytes) 222 case info.ContentType.Equal(OIDEncryptedData) || info.ContentType.Equal(SM2OIDEncryptedData): 223 return parseEncryptedData(info.Content.Bytes) 224 case info.ContentType.Equal(OIDSignedEnvelopedData) || info.ContentType.Equal(SM2OIDSignedEnvelopedData): 225 return parseSignedEnvelopedData(info.Content.Bytes) 226 default: 227 return nil, ErrUnsupportedContentType 228 } 229 } 230 231 func parseEnvelopedData(data []byte) (*PKCS7, error) { 232 var ed envelopedData 233 if _, err := asn1.Unmarshal(data, &ed); err != nil { 234 return nil, err 235 } 236 return &PKCS7{ 237 raw: ed, 238 }, nil 239 } 240 241 func parseEncryptedData(data []byte) (*PKCS7, error) { 242 var ed encryptedData 243 if _, err := asn1.Unmarshal(data, &ed); err != nil { 244 return nil, err 245 } 246 return &PKCS7{ 247 raw: ed, 248 }, nil 249 } 250 251 func (raw rawCertificates) Parse() ([]*smx509.Certificate, error) { 252 if len(raw.Raw) == 0 { 253 return nil, nil 254 } 255 256 var val asn1.RawValue 257 if _, err := asn1.Unmarshal(raw.Raw, &val); err != nil { 258 return nil, err 259 } 260 261 return smx509.ParseCertificates(val.Bytes) 262 } 263 264 func isCertMatchForIssuerAndSerial(cert *smx509.Certificate, ias issuerAndSerial) bool { 265 return cert.SerialNumber.Cmp(ias.SerialNumber) == 0 && bytes.Equal(cert.RawIssuer, ias.IssuerName.FullBytes) 266 } 267 268 // Attribute represents a key value pair attribute. Value must be marshalable byte 269 // `encoding/asn1` 270 type Attribute struct { 271 Type asn1.ObjectIdentifier 272 Value any 273 } 274 275 type attributes struct { 276 types []asn1.ObjectIdentifier 277 values []any 278 } 279 280 // Add adds the attribute, maintaining insertion order 281 func (attrs *attributes) Add(attrType asn1.ObjectIdentifier, value any) { 282 attrs.types = append(attrs.types, attrType) 283 attrs.values = append(attrs.values, value) 284 } 285 286 type sortableAttribute struct { 287 SortKey []byte 288 Attribute attribute 289 } 290 291 type attributeSet []sortableAttribute 292 293 func (sa attributeSet) Len() int { 294 return len(sa) 295 } 296 297 func (sa attributeSet) Less(i, j int) bool { 298 return bytes.Compare(sa[i].SortKey, sa[j].SortKey) < 0 299 } 300 301 func (sa attributeSet) Swap(i, j int) { 302 sa[i], sa[j] = sa[j], sa[i] 303 } 304 305 func (sa attributeSet) Attributes() []attribute { 306 attrs := make([]attribute, len(sa)) 307 for i, attr := range sa { 308 attrs[i] = attr.Attribute 309 } 310 return attrs 311 } 312 313 func (attrs *attributes) ForMarshalling() ([]attribute, error) { 314 sortables := make(attributeSet, len(attrs.types)) 315 for i := range sortables { 316 attrType := attrs.types[i] 317 attrValue := attrs.values[i] 318 asn1Value, err := asn1.Marshal(attrValue) 319 if err != nil { 320 return nil, err 321 } 322 attr := attribute{ 323 Type: attrType, 324 Value: asn1.RawValue{Tag: 17, IsCompound: true, Bytes: asn1Value}, // 17 == SET tag 325 } 326 encoded, err := asn1.Marshal(attr) 327 if err != nil { 328 return nil, err 329 } 330 sortables[i] = sortableAttribute{ 331 SortKey: encoded, 332 Attribute: attr, 333 } 334 } 335 sort.Sort(sortables) 336 return sortables.Attributes(), nil 337 }