|
|
|
|
// Package cms reads the CMS signatures (RFC 5652) and the RFC 3161 time-stamp
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// tokens that spec §29.10 and §29.11 define, with the CAdES profile that
|
|
|
|
|
// AutoFirma and other signing applications produce, and checks them with a
|
|
|
|
|
// closed table of algorithms. It uses the standard library only.
|
|
|
|
|
//
|
|
|
|
|
// It checks the signature and the dates, never who issued a certificate or
|
|
|
|
|
// whether it was revoked: a validator of the country that corresponds does
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// that (spec §29.10). Object identifiers are compared by the bytes of their
|
|
|
|
|
// DER, so that an arc of any size is only an identifier that the table does
|
|
|
|
|
// not have.
|
|
|
|
|
package cms
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"crypto/sha1"
|
|
|
|
|
"crypto/sha256"
|
|
|
|
|
"crypto/sha512"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"hash"
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"g.activething.com/go/DateKeys/internal/der"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// ErrForm is the error of a signature or a token whose form breaks the
|
|
|
|
|
// profile of spec §29.10 or §29.11: the verdicts F1 and S2.
|
|
|
|
|
var ErrForm = errors.New("cms: the form breaks the profile")
|
|
|
|
|
|
|
|
|
|
// ErrAlgorithm is the error of a token that uses an algorithm outside the
|
|
|
|
|
// table of spec §29.10: the verdict S1.
|
|
|
|
|
var ErrAlgorithm = errors.New("cms: an algorithm outside the table")
|
|
|
|
|
|
|
|
|
|
func formErr(format string, args ...any) error {
|
|
|
|
|
return fmt.Errorf("%w: %s", ErrForm, fmt.Sprintf(format, args...))
|
|
|
|
|
}
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// oid returns the content of the DER of the object identifier s, written
|
|
|
|
|
// with dots: the bytes that this package compares.
|
|
|
|
|
func oid(s string) []byte {
|
|
|
|
|
parts := strings.Split(s, ".")
|
|
|
|
|
arcs := make([]uint64, len(parts))
|
|
|
|
|
for i, p := range parts {
|
|
|
|
|
n, err := strconv.ParseUint(p, 10, 64)
|
|
|
|
|
if err != nil || len(parts) < 2 {
|
|
|
|
|
panic("cms: a bad object identifier " + s)
|
|
|
|
|
}
|
|
|
|
|
arcs[i] = n
|
|
|
|
|
}
|
|
|
|
|
out := base128(nil, arcs[0]*40+arcs[1])
|
|
|
|
|
for _, a := range arcs[2:] {
|
|
|
|
|
out = base128(out, a)
|
|
|
|
|
}
|
|
|
|
|
return out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func base128(out []byte, v uint64) []byte {
|
|
|
|
|
var tmp [10]byte
|
|
|
|
|
i := len(tmp) - 1
|
|
|
|
|
tmp[i] = byte(v & 0x7f)
|
|
|
|
|
for v >>= 7; v > 0; v >>= 7 {
|
|
|
|
|
i--
|
|
|
|
|
tmp[i] = byte(v&0x7f) | 0x80
|
|
|
|
|
}
|
|
|
|
|
return append(out, tmp[i:]...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// oidOf returns the content of the object identifier element b.
|
|
|
|
|
func oidOf(b []byte) ([]byte, bool) {
|
|
|
|
|
if len(b) == 0 || b[0] != 0x06 {
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|
c, err := der.Content(b)
|
|
|
|
|
return c, err == nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The object identifiers of the profile.
|
|
|
|
|
var (
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
oidData = oid("1.2.840.113549.1.7.1")
|
|
|
|
|
oidSignedData = oid("1.2.840.113549.1.7.2")
|
|
|
|
|
oidContentType = oid("1.2.840.113549.1.9.3")
|
|
|
|
|
oidMessageDig = oid("1.2.840.113549.1.9.4")
|
|
|
|
|
oidSigCertV1 = oid("1.2.840.113549.1.9.16.2.12")
|
|
|
|
|
oidSigCertV2 = oid("1.2.840.113549.1.9.16.2.47")
|
|
|
|
|
oidSigTimeStamp = oid("1.2.840.113549.1.9.16.2.14")
|
|
|
|
|
oidTSTInfo = oid("1.2.840.113549.1.9.16.1.4")
|
|
|
|
|
oidRIOCSP = oid("1.3.6.1.5.5.7.16.2")
|
v0.16: a seal without accuracy proves nothing before the opening date
A valid seal is S4 only when its token carries accuracy and t plus the
accuracy is before round_time; otherwise S5, whose text gives the reason,
the first that holds: sealed after or too close, no accuracy under the BTSP
policy of ETSI EN 319 421 (0.4.0.2023.1.1), or no accuracy (spec v0.16,
29.7, 29.11). The line of a signer of F6 whose seal does not prove it says
so with the same reason. cms.Token gains HasAccuracy, Policy and BTSP;
Verdicts gain SealReason and SignerLine.Reason; EncryptFiles returns the
verdicts of the area it wrote in Result.Security, so that a writer warns of
a seal without accuracy (rule 19).
security_cms.json is made again: 143 cases, the seals about something else
with an accuracy of a second, and the new cases of 64 with seal_reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7 hours ago
|
|
|
// oidBTSP is the best practices time-stamp policy of ETSI EN 319 421,
|
|
|
|
|
// whose tokens carry accuracy (spec v0.16, §29.11).
|
|
|
|
|
oidBTSP = oid("0.4.0.2023.1.1")
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
oidSHA256 = oid("2.16.840.1.101.3.4.2.1")
|
|
|
|
|
oidSHA384 = oid("2.16.840.1.101.3.4.2.2")
|
|
|
|
|
oidSHA512 = oid("2.16.840.1.101.3.4.2.3")
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// SignedData is the part of a CMS SignedData that the profile uses.
|
|
|
|
|
type SignedData struct {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// Certs are the certificates that meet the profile of §29.10, each once:
|
|
|
|
|
// another one decides nothing, unless a SignerInfo names it.
|
|
|
|
|
Certs []*Cert
|
|
|
|
|
// OCSP are the OCSP responses of crls.
|
|
|
|
|
OCSP [][]byte
|
|
|
|
|
// Signers are the SignerInfo, in the order of the encoding.
|
|
|
|
|
Signers []*SignerInfo
|
|
|
|
|
// EContent is the content of a token, nil in a detached signature.
|
|
|
|
|
EContent []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SignerInfo is a SignerInfo with the certificate that its sid names.
|
|
|
|
|
type SignerInfo struct {
|
|
|
|
|
Cert *Cert
|
|
|
|
|
// DigestAlg and SigAlg are the algorithm identifiers as written.
|
|
|
|
|
DigestAlg, SigAlg algID
|
|
|
|
|
// SignedAttrs is the DER of the signedAttrs as stored, with the
|
|
|
|
|
// context tag [0]; the signature covers it with the tag of a SET.
|
|
|
|
|
SignedAttrs []byte
|
|
|
|
|
MessageDigest []byte
|
|
|
|
|
Signature []byte
|
|
|
|
|
// Token is the signature-time-stamp attribute, the DER of its
|
|
|
|
|
// ContentInfo, nil when there is none.
|
|
|
|
|
Token []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type algID struct {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
OID []byte // the content of the object identifier
|
|
|
|
|
Params []byte // the DER of the parameters, nil when absent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseAlgID(b []byte) (algID, error) {
|
|
|
|
|
id, kids, err := der.Split(b)
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || id != 0x30 || len(kids) < 1 || len(kids) > 2 {
|
|
|
|
|
return algID{}, formErr("an AlgorithmIdentifier")
|
|
|
|
|
}
|
|
|
|
|
var a algID
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
var ok bool
|
|
|
|
|
if a.OID, ok = oidOf(kids[0]); !ok {
|
|
|
|
|
return algID{}, formErr("an AlgorithmIdentifier without an object identifier")
|
|
|
|
|
}
|
|
|
|
|
if len(kids) == 2 {
|
|
|
|
|
a.Params = kids[1]
|
|
|
|
|
}
|
|
|
|
|
return a, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// hashOf returns the hash that an identifier of the table names, and false
|
|
|
|
|
// for any other.
|
|
|
|
|
func (a algID) hashOf() (func() hash.Hash, bool) {
|
|
|
|
|
if a.Params != nil && !bytes.Equal(a.Params, []byte{5, 0}) {
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|
switch {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
case bytes.Equal(a.OID, oidSHA256):
|
|
|
|
|
return sha256.New, true
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
case bytes.Equal(a.OID, oidSHA384):
|
|
|
|
|
return sha512.New384, true
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
case bytes.Equal(a.OID, oidSHA512):
|
|
|
|
|
return sha512.New, true
|
|
|
|
|
}
|
|
|
|
|
return nil, false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseSignature reads the detached CMS signature of an author-signature of
|
|
|
|
|
// alg 2 (spec §29.10), checking its form in the order of the spec.
|
|
|
|
|
func ParseSignature(b []byte) (*SignedData, error) {
|
|
|
|
|
return parse(b, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parse(b []byte, token bool) (*SignedData, error) {
|
|
|
|
|
if err := der.Check(b); err != nil {
|
|
|
|
|
return nil, formErr("%v", err)
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
id, ci, err := der.Split(b)
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || id != 0x30 || len(ci) != 2 || ci[1][0] != 0xa0 {
|
|
|
|
|
return nil, formErr("a ContentInfo")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if ct, ok := oidOf(ci[0]); !ok || !bytes.Equal(ct, oidSignedData) {
|
|
|
|
|
return nil, formErr("the content type is not id-signedData")
|
|
|
|
|
}
|
|
|
|
|
_, inner, err := der.Split(ci[1])
|
|
|
|
|
if err != nil || len(inner) != 1 || inner[0][0] != 0x30 {
|
|
|
|
|
return nil, formErr("a SignedData")
|
|
|
|
|
}
|
|
|
|
|
_, sd, err := der.Split(inner[0])
|
|
|
|
|
if err != nil || len(sd) < 4 || sd[0][0] != 0x02 || sd[1][0] != 0x31 || sd[2][0] != 0x30 {
|
|
|
|
|
return nil, formErr("a SignedData")
|
|
|
|
|
}
|
|
|
|
|
// digestAlgorithms: a SET OF in order.
|
|
|
|
|
_, algs, err := der.Split(sd[1])
|
|
|
|
|
if err != nil || !der.SetOfSorted(algs) {
|
|
|
|
|
return nil, formErr("digestAlgorithms is not a SET OF in DER order")
|
|
|
|
|
}
|
|
|
|
|
for _, a := range algs {
|
|
|
|
|
if _, err := parseAlgID(a); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
out := &SignedData{}
|
|
|
|
|
if err := parseEncap(sd[2], token, out); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
rest := sd[3:]
|
|
|
|
|
if len(rest) > 0 && rest[0][0] == 0xa0 {
|
|
|
|
|
if err := parseCerts(rest[0], out); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
rest = rest[1:]
|
|
|
|
|
}
|
|
|
|
|
if len(rest) > 0 && rest[0][0] == 0xa1 {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err := parseCRLs(rest[0], token, out); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
rest = rest[1:]
|
|
|
|
|
}
|
|
|
|
|
if len(rest) != 1 || rest[0][0] != 0x31 {
|
|
|
|
|
return nil, formErr("signerInfos")
|
|
|
|
|
}
|
|
|
|
|
_, infos, err := der.Split(rest[0])
|
|
|
|
|
if err != nil || len(infos) == 0 || !der.SetOfSorted(infos) {
|
|
|
|
|
return nil, formErr("signerInfos is not a SET OF in DER order, or is empty")
|
|
|
|
|
}
|
|
|
|
|
if token && len(infos) != 1 {
|
|
|
|
|
return nil, formErr("a token has one SignerInfo, not %d", len(infos))
|
|
|
|
|
}
|
|
|
|
|
used := map[*Cert]bool{}
|
|
|
|
|
for _, si := range infos {
|
|
|
|
|
s, err := parseSignerInfo(si, out, token)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if used[s.Cert] {
|
|
|
|
|
return nil, formErr("two SignerInfo for one certificate")
|
|
|
|
|
}
|
|
|
|
|
used[s.Cert] = true
|
|
|
|
|
out.Signers = append(out.Signers, s)
|
|
|
|
|
}
|
|
|
|
|
return out, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parseEncap checks encapContentInfo: id-data without content in a detached
|
|
|
|
|
// signature, and id-ct-TSTInfo with its content in a token.
|
|
|
|
|
func parseEncap(b []byte, token bool, out *SignedData) error {
|
|
|
|
|
_, kids, err := der.Split(b)
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || len(kids) < 1 || len(kids) > 2 {
|
|
|
|
|
return formErr("encapContentInfo")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
ct, ok := oidOf(kids[0])
|
|
|
|
|
if !ok {
|
|
|
|
|
return formErr("encapContentInfo")
|
|
|
|
|
}
|
|
|
|
|
if !token {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if !bytes.Equal(ct, oidData) || len(kids) != 1 {
|
|
|
|
|
return formErr("a signature is detached: id-data and no eContent")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if !bytes.Equal(ct, oidTSTInfo) || len(kids) != 2 || kids[1][0] != 0xa0 {
|
|
|
|
|
return formErr("a token holds a TSTInfo")
|
|
|
|
|
}
|
|
|
|
|
_, e, err := der.Split(kids[1])
|
|
|
|
|
if err != nil || len(e) != 1 || e[0][0] != 0x04 {
|
|
|
|
|
return formErr("eContent")
|
|
|
|
|
}
|
|
|
|
|
if out.EContent, err = der.Content(e[0]); err != nil {
|
|
|
|
|
return formErr("eContent")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// parseCerts reads certificates. A certificate that breaks the profile of
|
|
|
|
|
// §29.10 decides nothing, as one that no SignerInfo names: an intermediate of
|
|
|
|
|
// another form is not a reason to refuse a signature, and the sid of a signer
|
|
|
|
|
// whose certificate breaks it names none. Two copies of a certificate are one.
|
|
|
|
|
func parseCerts(b []byte, out *SignedData) error {
|
|
|
|
|
_, kids, err := der.Split(b)
|
|
|
|
|
if err != nil || !der.SetOfSorted(kids) {
|
|
|
|
|
return formErr("certificates is not a SET OF in DER order")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
for i, k := range kids {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if k[0] >= 0xa0 && k[0] <= 0xa3 { // another choice of CertificateChoices: it decides nothing
|
|
|
|
|
continue
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if k[0] != 0x30 {
|
|
|
|
|
return formErr("a CertificateChoice that is neither a certificate nor one of the other four choices")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if i > 0 && bytes.Equal(kids[i-1], k) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if c, err := ParseCert(k); err == nil {
|
|
|
|
|
out.Certs = append(out.Certs, c)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// parseCRLs reads crls: in a signature, only OCSP responses (spec §29.10 rule
|
|
|
|
|
// 3); in a token, whatever it holds decides nothing (§29.11).
|
|
|
|
|
func parseCRLs(b []byte, token bool, out *SignedData) error {
|
|
|
|
|
_, kids, err := der.Split(b)
|
|
|
|
|
if err != nil || !der.SetOfSorted(kids) {
|
|
|
|
|
return formErr("crls is not a SET OF in DER order")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if token {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
for _, k := range kids {
|
|
|
|
|
if k[0] != 0xa1 {
|
|
|
|
|
return formErr("crls holds only OCSP responses")
|
|
|
|
|
}
|
|
|
|
|
_, f, err := der.Split(k)
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || len(f) != 2 {
|
|
|
|
|
return formErr("an OtherRevocationInfoFormat")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if o, ok := oidOf(f[0]); !ok || !bytes.Equal(o, oidRIOCSP) {
|
|
|
|
|
return formErr("crls holds only OCSP responses")
|
|
|
|
|
}
|
|
|
|
|
out.OCSP = append(out.OCSP, f[1])
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseSignerInfo(b []byte, sd *SignedData, token bool) (*SignerInfo, error) {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
id, f, err := der.Split(b)
|
|
|
|
|
if err != nil || id != 0x30 || len(f) < 6 || f[0][0] != 0x02 || f[2][0] != 0x30 || f[3][0] != 0xa0 || f[4][0] != 0x30 || f[5][0] != 0x04 {
|
|
|
|
|
return nil, formErr("a SignerInfo with signedAttrs")
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// RFC 5652 5.3: version 1 with issuerAndSerialNumber, version 3 with
|
|
|
|
|
// subjectKeyIdentifier.
|
|
|
|
|
if v, _ := der.Content(f[0]); !(len(v) == 1 && (v[0] == 1 && f[1][0] == 0x30 || v[0] == 3 && f[1][0] == 0x80)) {
|
|
|
|
|
return nil, formErr("the version of a SignerInfo does not match its sid")
|
|
|
|
|
}
|
|
|
|
|
s := &SignerInfo{SignedAttrs: f[3]}
|
|
|
|
|
if s.Cert, err = findSigner(f[1], sd.Certs); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if s.DigestAlg, err = parseAlgID(f[2]); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if s.SigAlg, err = parseAlgID(f[4]); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if s.Signature, err = der.Content(f[5]); err != nil {
|
|
|
|
|
return nil, formErr("signature")
|
|
|
|
|
}
|
|
|
|
|
if len(f) > 7 || len(f) == 7 && f[6][0] != 0xa1 {
|
|
|
|
|
return nil, formErr("a SignerInfo with something after its signature")
|
|
|
|
|
}
|
|
|
|
|
if err := parseSignedAttrs(s, token); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
if len(f) == 7 {
|
|
|
|
|
if err := parseUnsignedAttrs(s, f[6]); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return s, nil
|
|
|
|
|
}
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// findSigner returns the one certificate that the sid names, comparing the
|
|
|
|
|
// DER of the issuer and the content of the serial number, or the
|
|
|
|
|
// keyIdentifier.
|
|
|
|
|
func findSigner(sid []byte, certs []*Cert) (*Cert, error) {
|
|
|
|
|
var found *Cert
|
|
|
|
|
n := 0
|
|
|
|
|
switch sid[0] {
|
|
|
|
|
case 0x30: // issuerAndSerialNumber
|
|
|
|
|
_, p, err := der.Split(sid)
|
|
|
|
|
if err != nil || len(p) != 2 || p[0][0] != 0x30 || p[1][0] != 0x02 {
|
|
|
|
|
return nil, formErr("issuerAndSerialNumber")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
serial, _ := der.Content(p[1])
|
|
|
|
|
for _, c := range certs {
|
|
|
|
|
if c.hasSID(p[0], serial) {
|
|
|
|
|
found, n = c, n+1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 0x80: // subjectKeyIdentifier
|
|
|
|
|
ski, err := der.Content(sid)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, formErr("subjectKeyIdentifier")
|
|
|
|
|
}
|
|
|
|
|
for _, c := range certs {
|
|
|
|
|
if c.SKI != nil && bytes.Equal(c.SKI, ski) {
|
|
|
|
|
found, n = c, n+1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return nil, formErr("a SignerIdentifier")
|
|
|
|
|
}
|
|
|
|
|
if n != 1 {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
return nil, formErr("a sid that names %d certificates of the profile, not one", n)
|
|
|
|
|
}
|
|
|
|
|
return found, nil
|
|
|
|
|
}
|
|
|
|
|
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// attrSet holds the attributes of a SET OF Attribute: the values of each type
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// and the number of attributes of each type, which is not the number of
|
|
|
|
|
// values. Both are kept by the bytes of the object identifier.
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
type attrSet struct {
|
|
|
|
|
vals map[string][][]byte
|
|
|
|
|
count map[string]int
|
|
|
|
|
}
|
|
|
|
|
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
func (a attrSet) get(o []byte) ([][]byte, int) {
|
|
|
|
|
return a.vals[string(o)], a.count[string(o)]
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// attrs reads the SET OF Attribute b. An attribute needs at least one value
|
|
|
|
|
// (RFC 5652 5.3), so that two attributes of one type never hide behind an empty
|
|
|
|
|
// set of values.
|
|
|
|
|
func attrs(b []byte) (attrSet, error) {
|
|
|
|
|
_, kids, err := der.Split(b)
|
|
|
|
|
if err != nil || !der.SetOfSorted(kids) {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
return attrSet{}, formErr("attributes are not a SET OF in DER order")
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
out := attrSet{vals: map[string][][]byte{}, count: map[string]int{}}
|
|
|
|
|
for _, a := range kids {
|
|
|
|
|
_, p, err := der.Split(a)
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || len(p) != 2 || a[0] != 0x30 || p[1][0] != 0x31 {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
return attrSet{}, formErr("an Attribute")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
o, ok := oidOf(p[0])
|
|
|
|
|
if !ok {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
return attrSet{}, formErr("an Attribute")
|
|
|
|
|
}
|
|
|
|
|
_, vals, err := der.Split(p[1])
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if err != nil || len(vals) == 0 || !der.SetOfSorted(vals) {
|
|
|
|
|
return attrSet{}, formErr("the values of an attribute are not a non-empty SET OF in DER order")
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
out.vals[string(o)] = append(out.vals[string(o)], vals...)
|
|
|
|
|
out.count[string(o)]++
|
|
|
|
|
}
|
|
|
|
|
return out, nil
|
|
|
|
|
}
|
|
|
|
|
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// one returns the only value of the only attribute of the type.
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
func one(m attrSet, o []byte, name string) ([]byte, error) {
|
|
|
|
|
v, n := m.get(o)
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if n != 1 || len(v) != 1 {
|
|
|
|
|
return nil, formErr("%s: %d attributes with %d values, not one with one", name, n, len(v))
|
|
|
|
|
}
|
|
|
|
|
return v[0], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parseSignedAttrs checks the signedAttrs of the profile (spec §29.10 rule 4,
|
|
|
|
|
// §29.11): content-type, message-digest and the signing certificate.
|
|
|
|
|
func parseSignedAttrs(s *SignerInfo, token bool) error {
|
|
|
|
|
m, err := attrs(s.SignedAttrs)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// Each of the three is one attribute with one value.
|
|
|
|
|
ct, err := one(m, oidContentType, "content-type")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
want, name := oidData, "id-data"
|
|
|
|
|
if token {
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
want, name = oidTSTInfo, "id-ct-TSTInfo"
|
|
|
|
|
}
|
CMS reader: its own certificate profile, identifiers by their bytes
Fixes of the review of the session of 1 and 2 October in internal/cms and
internal/der:
- Object identifiers are compared by the bytes of their DER: an arc of 2^31
or more no longer makes an attribute that decides nothing fail the
signature (F1), and an algorithm with one is outside the table (F5, S1),
as spec v0.11 says.
- A SET OF may repeat an element, as X.690 allows: a TSA that sends its
certificate twice no longer gives S2. Two copies of a certificate are one.
- Certificates are read with a profile of their own instead of
encoding/asn1 and crypto/x509, field by field, so that a second
implementation can read them the same: version 3, the fields in order,
names of non-empty SETs, times of validity in DER without a fraction,
extensions without repetition, and the text of a name only from
UTF8String, PrintableString, IA5String, TeletexString in ASCII and
BMPString without surrogates, nothing removed from it. A certificate that
breaks the profile decides nothing unless a SignerInfo names it. The
holder is givenName and surname before commonName, which in the
certificates of the FNMT carries the NIF; the issuer is its commonName or
its organizationName.
- The key: RSA with NULL parameters, exactly a modulus and an exponent, the
modulus odd; EC only uncompressed on P-256, P-384 and P-521.
- A key of another scheme than its algorithm is invalid (F2) and not
outside the table (F5), as step 3 of 29.10 says; a messageImprint of
another length is S3; the crls of a token decide nothing.
- DER: UTCTime and GeneralizedTime in their forms of X.690, a date that
exists, and the millis and micros of accuracy as minimal INTEGERs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
if got, ok := oidOf(ct); !ok || !bytes.Equal(got, want) {
|
|
|
|
|
return formErr("content-type is not %s", name)
|
|
|
|
|
}
|
|
|
|
|
md, err := one(m, oidMessageDig, "message-digest")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if md[0] != 0x04 {
|
|
|
|
|
return formErr("message-digest is not an OCTET STRING")
|
|
|
|
|
}
|
|
|
|
|
if s.MessageDigest, err = der.Content(md); err != nil {
|
|
|
|
|
return formErr("message-digest")
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
// signing-certificate-v2 is the one that counts: a signature has it, and a
|
|
|
|
|
// token has it or, failing that, signing-certificate. The other attributes
|
|
|
|
|
// decide nothing, a signing-certificate beside the v2 among them.
|
|
|
|
|
v2, n2 := m.get(oidSigCertV2)
|
|
|
|
|
v1, n1 := m.get(oidSigCertV1)
|
|
|
|
|
switch {
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
case n2 == 1 && len(v2) == 1:
|
|
|
|
|
return checkESSCert(s.Cert, v2[0], true)
|
|
|
|
|
case token && n2 == 0 && n1 == 1 && len(v1) == 1:
|
|
|
|
|
return checkESSCert(s.Cert, v1[0], false)
|
|
|
|
|
}
|
|
|
|
|
return formErr("signing-certificate: one attribute of one value is required")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// checkESSCert checks that the first ESSCertID of a signing-certificate or
|
|
|
|
|
// signing-certificate-v2 (RFC 2634, RFC 5035) is the hash of the certificate.
|
|
|
|
|
func checkESSCert(c *Cert, v []byte, v2 bool) error {
|
|
|
|
|
id, sc, err := der.Split(v)
|
|
|
|
|
if err != nil || id != 0x30 || len(sc) < 1 || sc[0][0] != 0x30 {
|
|
|
|
|
return formErr("a SigningCertificate")
|
|
|
|
|
}
|
|
|
|
|
_, ids, err := der.Split(sc[0])
|
|
|
|
|
if err != nil || len(ids) < 1 || ids[0][0] != 0x30 {
|
|
|
|
|
return formErr("an ESSCertID")
|
|
|
|
|
}
|
|
|
|
|
_, f, err := der.Split(ids[0])
|
|
|
|
|
if err != nil || len(f) < 1 {
|
|
|
|
|
return formErr("an ESSCertID")
|
|
|
|
|
}
|
|
|
|
|
newHash := sha1.New
|
|
|
|
|
if v2 {
|
|
|
|
|
newHash = sha256.New
|
|
|
|
|
if f[0][0] == 0x30 { // hashAlgorithm, which defaults to SHA-256
|
|
|
|
|
a, err := parseAlgID(f[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
h, ok := a.hashOf()
|
|
|
|
|
if !ok {
|
|
|
|
|
return formErr("the hash of the ESSCertIDv2 is outside the table")
|
|
|
|
|
}
|
|
|
|
|
newHash, f = h, f[1:]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(f) < 1 || f[0][0] != 0x04 {
|
|
|
|
|
return formErr("certHash")
|
|
|
|
|
}
|
|
|
|
|
hv, err := der.Content(f[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return formErr("certHash")
|
|
|
|
|
}
|
|
|
|
|
h := newHash()
|
|
|
|
|
h.Write(c.Raw)
|
|
|
|
|
if !bytes.Equal(h.Sum(nil), hv) {
|
|
|
|
|
return formErr("the certHash is not that of the certificate of the signer")
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// parseUnsignedAttrs reads the signature-time-stamp, at most one with one
|
|
|
|
|
// value (spec §29.10 rule 4); the other attributes decide nothing.
|
|
|
|
|
func parseUnsignedAttrs(s *SignerInfo, b []byte) error {
|
|
|
|
|
m, err := attrs(b)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
switch v, n := m.get(oidSigTimeStamp); {
|
|
|
|
|
case n == 0:
|
|
|
|
|
case n == 1 && len(v) == 1:
|
|
|
|
|
s.Token = v[0]
|
|
|
|
|
default:
|
Review fixes: the CMS reader, the area after the signature, and the issuer on screen
The TSTInfo is read field by field in DER, with accuracy from zero and
millis and micros from 1 to 999, genTime in UTC with Z, no default written
and nothing after the last field. The ContentInfo and the SignerInfo must be
SEQUENCEs, a SignerInfo version must match its sid, an attribute needs a
value and is counted by attribute and not by value, a signing-certificate
beside the v2 decides nothing, PSS parameters come in order without the
trailer, and der.Check refuses the end of contents and the universal tags
the profile does not use.
The writer signs before L is fixed: write asks prepare for the final L, so
the area grows to 64 KiB only when what was signed does not fit and LargeArea
allows it, and nobody signs twice for it. Typed nils are nil, the exclusions
are checked before a file is read, Encrypt refuses the signing options, and
EvaluateSecurityIn gives X if a parser panics. The issuer of a certificate is
filtered like its holder.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
6 days ago
|
|
|
return formErr("signature-time-stamp: %d attributes with %d values, not one with one", n, len(v))
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|