You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/internal/cms/verify.go

439 lines
13 KiB

package cms
import (
"bytes"
"crypto"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"errors"
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
"math/big"
"time"
"g.activething.com/go/DateKeys/internal/der"
)
// Result is the result of checking the signature of a SignerInfo (spec
// §29.10, "Verificación").
type Result int
const (
// Valid: the message-digest is the hash of the message and the signature
// of the signedAttrs verifies with the key of the certificate.
Valid Result = iota
// Invalid: one of the two does not hold.
Invalid
// NotVerifiable: an algorithm, a key size or a curve outside the table.
NotVerifiable
)
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
oidRSAEncryption = oid("1.2.840.113549.1.1.1")
oidSHA256RSA = oid("1.2.840.113549.1.1.11")
oidSHA384RSA = oid("1.2.840.113549.1.1.12")
oidSHA512RSA = oid("1.2.840.113549.1.1.13")
oidPSS = oid("1.2.840.113549.1.1.10")
oidMGF1 = oid("1.2.840.113549.1.1.8")
oidECDSA256 = oid("1.2.840.10045.4.3.2")
oidECDSA384 = oid("1.2.840.10045.4.3.3")
oidECDSA512 = oid("1.2.840.10045.4.3.4")
oidECPublicKey = oid("1.2.840.10045.2.1")
oidP256 = oid("1.2.840.10045.3.1.7")
oidP384 = oid("1.3.132.0.34")
oidP521 = oid("1.3.132.0.35")
)
type scheme int
const (
schemePKCS1 scheme = iota + 1
schemePSS
schemeECDSA
)
// params returns the hash, the signature scheme and the hash that the
// signature algorithm itself names, when it does, of the SignerInfo, and
// whether they are in the table.
func (s *SignerInfo) params() (crypto.Hash, scheme, bool) {
newHash, ok := s.DigestAlg.hashOf()
if !ok {
return 0, 0, false
}
var h crypto.Hash
switch newHash().Size() {
case 32:
h = crypto.SHA256
case 48:
h = crypto.SHA384
default:
h = crypto.SHA512
}
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, params := s.SigAlg.OID, s.SigAlg.Params
nullOrAbsent := params == nil || bytes.Equal(params, []byte{5, 0})
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(o, oidRSAEncryption):
return h, schemePKCS1, nullOrAbsent
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(o, oidSHA256RSA):
return h, schemePKCS1, nullOrAbsent && h == crypto.SHA256
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(o, oidSHA384RSA):
return h, schemePKCS1, nullOrAbsent && h == crypto.SHA384
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(o, oidSHA512RSA):
return h, schemePKCS1, nullOrAbsent && h == crypto.SHA512
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(o, oidECDSA256):
return h, schemeECDSA, params == nil && h == crypto.SHA256
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(o, oidECDSA384):
return h, schemeECDSA, params == nil && h == crypto.SHA384
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(o, oidECDSA512):
return h, schemeECDSA, params == nil && h == crypto.SHA512
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(o, oidPSS):
return h, schemePSS, pssParamsOK(params, newHash().Size(), s.DigestAlg)
}
return 0, 0, false
}
// pssParamsOK checks RSASSA-PSS-params (RFC 4055): the hash of digestAlgorithm,
// MGF1 with that hash, a salt of its length and trailerField 1.
func pssParamsOK(params []byte, hashLen int, digest algID) bool {
if params == nil {
return false
}
id, f, err := der.Split(params)
if err != nil || id != 0x30 {
return false
}
var hashOK, mgfOK, saltOK bool
var last byte
for _, e := range f {
_, in, err := der.Split(e)
if err != nil || len(in) != 1 || e[0] <= last {
return false // the fields come in order of tag, each once
}
last = e[0]
switch e[0] {
case 0xa0:
a, err := parseAlgID(in[0])
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
hashOK = err == nil && bytes.Equal(a.OID, digest.OID) && (a.Params == nil || bytes.Equal(a.Params, []byte{5, 0}))
case 0xa1:
a, err := parseAlgID(in[0])
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 || !bytes.Equal(a.OID, oidMGF1) || a.Params == nil {
return false
}
inner, err := parseAlgID(a.Params)
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
mgfOK = err == nil && bytes.Equal(inner.OID, digest.OID) && (inner.Params == nil || bytes.Equal(inner.Params, []byte{5, 0}))
case 0xa2:
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
n, ok := smallInt(in[0])
saltOK = ok && n == hashLen
default: // [3] trailerField is 1, its DEFAULT: DER does not write it
return false
}
}
// hashAlgorithm and maskGenAlgorithm default to SHA-1, and the salt to 20
// bytes: none of them is in the table, so each must be present.
return hashOK && mgfOK && saltOK
}
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
// smallInt reads an INTEGER element of at most 4 bytes that is not negative.
func smallInt(b []byte) (int, bool) {
if len(b) == 0 || b[0] != 0x02 {
return 0, false
}
c, err := der.Content(b)
if err != nil || len(c) == 0 || len(c) > 4 || c[0]&0x80 != 0 {
return 0, false
}
n := 0
for _, x := range c {
n = n<<8 | int(x)
}
return n, true
}
// publicKey returns the key of the certificate when the table has it (spec
// §29.10): a SubjectPublicKeyInfo of rsaEncryption with NULL parameters and
// an RSAPublicKey of exactly a modulus and an exponent, the modulus odd and
// of 2048 to 4096 bits and the exponent odd from 3 to 2^31 - 1; or of
// id-ecPublicKey with the named curve P-256, P-384 or P-521 and the
// uncompressed form of a point of it. Anything else is not usable.
func (c *Cert) publicKey() (any, scheme, bool) {
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
_, f, err := der.Split(c.SPKI)
if err != nil || len(f) != 2 || f[0][0] != 0x30 || f[1][0] != 0x03 {
return nil, 0, false
}
alg, err := parseAlgID(f[0])
if err != nil {
return nil, 0, false
}
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
bits, err := der.Content(f[1])
if err != nil || len(bits) < 2 || bits[0] != 0 {
return nil, 0, false
}
key := bits[1:]
switch {
case bytes.Equal(alg.OID, oidRSAEncryption) && bytes.Equal(alg.Params, []byte{5, 0}):
if der.Check(key) != nil {
return nil, 0, false
}
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
id, ne, err := der.Split(key)
if err != nil || id != 0x30 || len(ne) != 2 || ne[0][0] != 0x02 || ne[1][0] != 0x02 {
return nil, 0, false
}
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
nb, _ := der.Content(ne[0])
eb, _ := der.Content(ne[1])
if nb[0]&0x80 != 0 || eb[0]&0x80 != 0 || len(eb) > 4 {
return nil, 0, false
}
n := new(big.Int).SetBytes(nb)
e := new(big.Int).SetBytes(eb).Int64()
if b := n.BitLen(); b < 2048 || b > 4096 || n.Bit(0) == 0 || e < 3 || e%2 == 0 || e > 1<<31-1 {
return nil, 0, false
}
return &rsa.PublicKey{N: n, E: int(e)}, schemePKCS1, true
case bytes.Equal(alg.OID, oidECPublicKey):
curveOID, ok := oidOf(alg.Params)
if !ok {
return nil, 0, false
}
var curve elliptic.Curve
switch {
case bytes.Equal(curveOID, oidP256):
curve = elliptic.P256()
case bytes.Equal(curveOID, oidP384):
curve = elliptic.P384()
case bytes.Equal(curveOID, oidP521):
curve = elliptic.P521()
default:
return nil, 0, false
}
k, err := ecdsa.ParseUncompressedPublicKey(curve, key)
if err != nil {
return nil, 0, false
}
return k, schemeECDSA, true
}
return nil, 0, false
}
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
// Check checks the signature of the SignerInfo over message, the bytes that
// the signature is detached from (spec §29.10), in the order of the spec: not
// verifiable for an algorithm, a key or a curve outside the table; invalid
// when the message-digest is not the hash of message, or the signature of the
// signedAttrs does not verify with the key of the certificate, which is the
// case of a key of a scheme other than the one of the algorithm.
func (s *SignerInfo) Check(message []byte) Result {
h, sch, ok := s.params()
if !ok {
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 NotVerifiable
}
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
key, ksch, ok := s.Cert.publicKey()
if !ok {
return NotVerifiable
}
if sum := hashBytes(h, message); !bytes.Equal(sum, s.MessageDigest) {
return Invalid
}
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 sch != ksch && !(sch == schemePSS && ksch == schemePKCS1) {
return Invalid
}
// The signature covers the signedAttrs with the tag of a SET.
attrs := bytes.Clone(s.SignedAttrs)
attrs[0] = 0x31
digest := hashBytes(h, attrs)
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 valid bool
switch k := key.(type) {
case *rsa.PublicKey:
if sch == schemePSS {
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
valid = rsa.VerifyPSS(k, h, digest, s.Signature, &rsa.PSSOptions{SaltLength: h.Size(), Hash: h}) == nil
} else {
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
valid = rsa.VerifyPKCS1v15(k, h, digest, s.Signature) == nil
}
case *ecdsa.PublicKey:
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
valid = ecdsa.VerifyASN1(k, digest, s.Signature)
}
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 !valid {
return Invalid
}
return Valid
}
func hashBytes(h crypto.Hash, b []byte) []byte {
x := h.New()
x.Write(b)
return x.Sum(nil)
}
// Token is a time-stamp token of RFC 3161 read with the profile of spec
// §29.11.
type Token struct {
// GenTime is t, and Accuracy the precision of the token, zero when it
// has none.
GenTime time.Time
Accuracy time.Duration
// ImprintAlg is the hash of the messageImprint, and Imprint the 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
ImprintAlg algID
Imprint []byte
// TSA is the certificate of the time-stamping authority.
TSA *Cert
data *SignedData
}
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
// maxAccuracy bounds the seconds of accuracy (spec §29.11): far above any
// real one, and far below what would overflow a Duration.
const maxAccuracy = 1<<31 - 1
// ParseToken reads a time-stamp token. It fails with ErrForm when the form
// breaks the profile, and with ErrAlgorithm when an algorithm is outside the
// table, in that order (spec §29.11): the verdicts S2 and S1.
func ParseToken(b []byte) (*Token, error) {
sd, err := parse(b, true)
if err != nil {
return nil, err
}
// The TSTInfo is an OCTET STRING inside the token, so the check of the
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
// token did not reach it: it is read here, field by field.
t, imprintAlg, hash, err := parseTSTInfo(sd.EContent)
if err != nil {
return nil, err
}
t.TSA, t.data = sd.Signers[0].Cert, sd
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 t.ImprintAlg, err = parseAlgID(imprintAlg); err != nil {
return nil, 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
t.Imprint = hash
if _, ok := t.ImprintAlg.hashOf(); !ok {
return nil, ErrAlgorithm
}
if _, _, ok := sd.Signers[0].params(); !ok {
return nil, ErrAlgorithm
}
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 _, _, ok := t.TSA.publicKey(); !ok {
return nil, ErrAlgorithm
}
return t, nil
}
// parseTSTInfo reads the TSTInfo of RFC 3161 3.2.1 in DER: the fields in
// order, each once, and nothing after the last. It returns the messageImprint
// algorithm, as the DER of its AlgorithmIdentifier, and the hash.
func parseTSTInfo(b []byte) (*Token, []byte, []byte, error) {
bad := func(what string) (*Token, []byte, []byte, error) {
return nil, nil, nil, formErr("the TSTInfo: %s", what)
}
if err := der.Check(b); err != nil {
return bad(err.Error())
}
id, f, err := der.Split(b)
if err != nil || id != 0x30 || len(f) < 5 {
return bad("not a SEQUENCE of at least five fields")
}
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 v, ok := smallInt(f[0]); !ok || v != 1 {
return bad("the version is not 1")
}
if f[1][0] != 0x06 || f[3][0] != 0x02 || f[4][0] != 0x18 {
return bad("policy, serialNumber or genTime")
}
_, mi, err := der.Split(f[2])
if f[2][0] != 0x30 || err != nil || len(mi) != 2 || mi[0][0] != 0x30 || mi[1][0] != 0x04 {
return bad("the messageImprint")
}
hash, err := der.Content(mi[1])
if err != nil {
return bad("the messageImprint")
}
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
gen, _, err := der.ParseTime(f[4])
if err != 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
return bad("genTime: " + err.Error())
}
t := &Token{GenTime: gen}
rest := f[5:]
if len(rest) > 0 && rest[0][0] == 0x30 {
if t.Accuracy, err = parseAccuracy(rest[0]); err != nil {
return bad(err.Error())
}
rest = rest[1:]
}
if len(rest) > 0 && rest[0][0] == 0x01 {
if c, _ := der.Content(rest[0]); len(c) != 1 || c[0] != 0xff {
return bad("ordering FALSE is its default and DER does not write it")
}
rest = rest[1:]
}
if len(rest) > 0 && rest[0][0] == 0x02 { // nonce
rest = rest[1:]
}
if len(rest) > 0 && rest[0][0] == 0xa0 { // tsa
rest = rest[1:]
}
if len(rest) > 0 && rest[0][0] == 0xa1 { // extensions
rest = rest[1:]
}
if len(rest) != 0 {
return bad("a field out of its place, or one that does not exist")
}
return t, mi[0], hash, 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
// parseAccuracy reads Accuracy: seconds from 0 to 2^31 - 1, and millis and
// micros from 1 to 999, in that order, each optional (RFC 3161 2.4.2, spec
// §29.11), each a minimal INTEGER. A negative number would make a seal after
// the opening date look before it.
func parseAccuracy(b []byte) (time.Duration, error) {
_, f, err := der.Split(b)
if err != nil {
return 0, errors.New("accuracy")
}
var total time.Duration
if len(f) > 0 && f[0][0] == 0x02 {
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
secs, ok := smallInt(f[0])
if !ok || secs > maxAccuracy {
return 0, errors.New("accuracy seconds outside 0 to 2^31 - 1")
}
total += time.Duration(secs) * time.Second
f = f[1:]
}
for _, part := range []struct {
tag byte
unit time.Duration
}{{0x80, time.Millisecond}, {0x81, time.Microsecond}} {
if len(f) > 0 && f[0][0] == part.tag {
c, err := der.Content(f[0])
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(c) < 1 || len(c) > 2 || c[0]&0x80 != 0 || len(c) == 2 && c[0] == 0 && c[1]&0x80 == 0 {
return 0, errors.New("accuracy millis or micros that are not a minimal INTEGER")
}
n := 0
for _, x := range c {
n = n<<8 | int(x)
}
if n < 1 || n > 999 {
return 0, errors.New("accuracy millis or micros outside 1 to 999")
}
total += time.Duration(n) * part.unit
f = f[1:]
}
}
if len(f) != 0 {
return 0, errors.New("accuracy has a field out of its place")
}
return total, nil
}
// ImprintIsSHA256 reports whether the messageImprint uses SHA-256, which a
// seal of seal_type 2 requires (spec §29.11).
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 (t *Token) ImprintIsSHA256() bool { return bytes.Equal(t.ImprintAlg.OID, oidSHA256) }
// Check verifies the token over subject, the bytes that it seals: the
// message-digest is the hash of the TSTInfo, the signature of the TSA
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
// verifies, the messageImprint is the hash of subject, of any length, and the
// certificate of the TSA is valid at genTime. It returns false for the
// verdict S3.
func (t *Token) Check(subject []byte) bool {
s := t.data.Signers[0]
if s.Check(t.data.EContent) != Valid {
return false
}
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
newHash, _ := t.ImprintAlg.hashOf()
h := newHash()
h.Write(subject)
return bytes.Equal(h.Sum(nil), t.Imprint) && t.TSA.ValidAt(t.GenTime)
}

Powered by TurnKey Linux.