1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
// Copyright The Notary Project Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package cms verifies Signed-Data defined in RFC 5652 Cryptographic Message
// Syntax (CMS) / PKCS7
//
// References:
// - RFC 5652 Cryptographic Message Syntax (CMS)
package cms
import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"math/big"
)
// ContentInfo struct is used to represent the content of a CMS message,
// which can be encrypted, signed, or both.
//
// References: RFC 5652 3 ContentInfo Type
//
// ContentInfo ::= SEQUENCE {
// contentType ContentType,
// content [0] EXPLICIT ANY DEFINED BY contentType }
type ContentInfo struct {
// ContentType field specifies the type of the content, which can be one of
// several predefined types, such as data, signedData, envelopedData, or
// encryptedData. Only signedData is supported currently.
ContentType asn1.ObjectIdentifier
// Content field contains the actual content of the message.
Content asn1.RawValue `asn1:"explicit,tag:0"`
}
// SignedData struct is used to represent a signed CMS message, which contains
// one or more signatures that are used to verify the authenticity and integrity
// of the message.
//
// Reference: RFC 5652 5.1 SignedData
//
// SignedData ::= SEQUENCE {
// version CMSVersion,
// digestAlgorithms DigestAlgorithmIdentifiers,
// encapContentInfo EncapsulatedContentInfo,
// certificates [0] IMPLICIT CertificateSet OPTIONAL,
// crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
// signerInfos SignerInfos }
type SignedData struct {
// Version field specifies the syntax version number of the SignedData.
Version int
// DigestAlgorithmIdentifiers field specifies the digest algorithms used
// by one or more signatures in SignerInfos.
DigestAlgorithmIdentifiers []pkix.AlgorithmIdentifier `asn1:"set"`
// EncapsulatedContentInfo field specifies the content that is signed.
EncapsulatedContentInfo EncapsulatedContentInfo
// Certificates field contains the certificates that are used to verify the
// signatures in SignerInfos.
Certificates asn1.RawValue `asn1:"optional,tag:0"`
// CRLs field contains the Certificate Revocation Lists that are used to
// verify the signatures in SignerInfos.
CRLs []x509.RevocationList `asn1:"optional,tag:1"`
// SignerInfos field contains one or more signatures.
SignerInfos []SignerInfo `asn1:"set"`
}
// EncapsulatedContentInfo struct is used to represent the content of a CMS
// message.
//
// References: RFC 5652 5.2 EncapsulatedContentInfo
//
// EncapsulatedContentInfo ::= SEQUENCE {
// eContentType ContentType,
// eContent [0] EXPLICIT OCTET STRING OPTIONAL }
type EncapsulatedContentInfo struct {
// ContentType is an object identifier. The object identifier uniquely
// specifies the content type.
ContentType asn1.ObjectIdentifier
// Content field contains the actual content of the message.
Content []byte `asn1:"explicit,optional,tag:0"`
}
// SignerInfo struct is used to represent a signature and related information
// that is needed to verify the signature.
//
// Reference: RFC 5652 5.3 SignerInfo
//
// SignerInfo ::= SEQUENCE {
// version CMSVersion,
// sid SignerIdentifier,
// digestAlgorithm DigestAlgorithmIdentifier,
// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
// signatureAlgorithm SignatureAlgorithmIdentifier,
// signature SignatureValue,
// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
//
// Only version 1 is supported. As defined in RFC 5652 5.3, SignerIdentifier
// is IssuerAndSerialNumber when version is 1.
type SignerInfo struct {
// Version field specifies the syntax version number of the SignerInfo.
Version int
// SignerIdentifier field specifies the signer's certificate. Only IssuerAndSerialNumber
// is supported currently.
SignerIdentifier IssuerAndSerialNumber
// DigestAlgorithm field specifies the digest algorithm used by the signer.
DigestAlgorithm pkix.AlgorithmIdentifier
// SignedAttributes field contains a collection of attributes that are
// signed.
SignedAttributes Attributes `asn1:"optional,tag:0"`
// SignatureAlgorithm field specifies the signature algorithm used by the
// signer.
SignatureAlgorithm pkix.AlgorithmIdentifier
// Signature field contains the actual signature.
Signature []byte
// UnsignedAttributes field contains a collection of attributes that are
// not signed.
UnsignedAttributes Attributes `asn1:"optional,tag:1"`
}
// IssuerAndSerialNumber struct is used to identify a certificate.
//
// Reference: RFC 5652 5.3 SignerIdentifier
//
// IssuerAndSerialNumber ::= SEQUENCE {
// issuer Name,
// serialNumber CertificateSerialNumber }
type IssuerAndSerialNumber struct {
// Issuer field identifies the certificate issuer.
Issuer asn1.RawValue
// SerialNumber field identifies the certificate.
SerialNumber *big.Int
}
// Attribute struct is used to represent a attribute with type and values.
//
// Reference: RFC 5652 5.3 SignerInfo
//
// Attribute ::= SEQUENCE {
// attrType OBJECT IDENTIFIER,
// attrValues SET OF AttributeValue }
type Attribute struct {
// Type field specifies the type of the attribute.
Type asn1.ObjectIdentifier
// Values field contains the actual value of the attribute.
Values asn1.RawValue `asn1:"set"`
}
// Attributes ::= SET SIZE (0..MAX) OF Attribute
type Attributes []Attribute
// Get tries to find the attribute by the given identifier, parse and store
// the result in the value pointed to by out.
func (a Attributes) Get(identifier asn1.ObjectIdentifier, out any) error {
for _, attribute := range a {
if identifier.Equal(attribute.Type) {
_, err := asn1.Unmarshal(attribute.Values.Bytes, out)
return err
}
}
return ErrAttributeNotFound
}
|