|
|
|
|
// Package der checks that bytes are one element in the Distinguished Encoding
|
|
|
|
|
// Rules of X.690, as spec v0.11 §29.10 asks of a CMS signature before it
|
|
|
|
|
// looks inside it: definite and minimal lengths, no high tag numbers, no
|
|
|
|
|
// constructed form of a type that DER only has primitive, canonical BOOLEAN,
|
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>
1 week ago
|
|
|
// INTEGER, NULL, OBJECT IDENTIFIER, BIT STRING, UTCTime and GeneralizedTime,
|
|
|
|
|
// and no bytes after the element. Go's encoding/asn1 accepts some of what DER
|
|
|
|
|
// forbids, and a signature that two implementations read the same must not
|
|
|
|
|
// depend on it.
|
|
|
|
|
//
|
|
|
|
|
// The order of the elements of a SET OF cannot be checked without a schema:
|
|
|
|
|
// SetOfSorted does it for the callers that know theirs.
|
|
|
|
|
package der
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
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>
1 week ago
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const maxDepth = 32
|
|
|
|
|
|
|
|
|
|
// Check returns nil when b is exactly one DER element.
|
|
|
|
|
func Check(b []byte) error {
|
|
|
|
|
n, err := check(b, 0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
if n != len(b) {
|
|
|
|
|
return fmt.Errorf("der: %d bytes after the element", len(b)-n)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Split returns the content of the DER element b, which must be constructed,
|
|
|
|
|
// as the encodings of its children, and the identifier octet of b. It
|
|
|
|
|
// assumes Check passed.
|
|
|
|
|
func Split(b []byte) (id byte, children [][]byte, err error) {
|
|
|
|
|
if len(b) == 0 || b[0]&0x20 == 0 {
|
|
|
|
|
return 0, nil, errors.New("der: not a constructed element")
|
|
|
|
|
}
|
|
|
|
|
hl, cl, err := header(b)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, nil, err
|
|
|
|
|
}
|
|
|
|
|
rest := b[hl : hl+cl]
|
|
|
|
|
for len(rest) > 0 {
|
|
|
|
|
h, c, err := header(rest)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, nil, err
|
|
|
|
|
}
|
|
|
|
|
children = append(children, rest[:h+c])
|
|
|
|
|
rest = rest[h+c:]
|
|
|
|
|
}
|
|
|
|
|
return b[0], children, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Content returns the content octets of the DER element b.
|
|
|
|
|
func Content(b []byte) ([]byte, error) {
|
|
|
|
|
hl, cl, err := header(b)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return b[hl : hl+cl], nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetOfSorted reports whether the encodings are in ascending order of their
|
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>
1 week ago
|
|
|
// bytes, as DER requires of the elements of a SET OF (X.690 11.6). Equal
|
|
|
|
|
// elements may repeat, side by side: X.690 does not forbid it, and a time-
|
|
|
|
|
// stamping authority may send its certificate twice. Whoever counts the
|
|
|
|
|
// elements of a SET OF decides what a repetition means.
|
|
|
|
|
func SetOfSorted(elems [][]byte) bool {
|
|
|
|
|
for i := 1; i < len(elems); i++ {
|
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>
1 week ago
|
|
|
if bytes.Compare(elems[i-1], elems[i]) > 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 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>
1 week ago
|
|
|
// ParseTime reads a UTCTime or a GeneralizedTime element as DER writes them
|
|
|
|
|
// (X.690 11.7 and 11.8): YYMMDDHHMMSSZ, with the years 50 to 99 in the 20th
|
|
|
|
|
// century (RFC 5280 4.1.2.5.1), or YYYYMMDDHHMMSS, an optional fraction of
|
|
|
|
|
// seconds without a trailing zero, and Z. A date or a time that does not
|
|
|
|
|
// exist, a second 60 included, is refused. fraction reports whether a
|
|
|
|
|
// GeneralizedTime has one.
|
|
|
|
|
func ParseTime(b []byte) (t time.Time, fraction bool, err error) {
|
|
|
|
|
if len(b) < 2 || (b[0] != 0x17 && b[0] != 0x18) {
|
|
|
|
|
return time.Time{}, false, errors.New("der: not a UTCTime or a GeneralizedTime")
|
|
|
|
|
}
|
|
|
|
|
c, err := Content(b)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return time.Time{}, false, err
|
|
|
|
|
}
|
|
|
|
|
return parseTime(b[0], string(c))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func parseTime(tag byte, s string) (time.Time, bool, error) {
|
|
|
|
|
bad := errors.New("der: a time that is not in the form of DER")
|
|
|
|
|
if len(s) < 13 || s[len(s)-1] != 'Z' {
|
|
|
|
|
return time.Time{}, false, bad
|
|
|
|
|
}
|
|
|
|
|
body, frac := s[:len(s)-1], ""
|
|
|
|
|
var year int
|
|
|
|
|
switch tag {
|
|
|
|
|
case 0x17:
|
|
|
|
|
if len(body) != 12 || !digits(body) {
|
|
|
|
|
return time.Time{}, false, bad
|
|
|
|
|
}
|
|
|
|
|
year = atoi(body[:2]) + 1900
|
|
|
|
|
if year < 1950 {
|
|
|
|
|
year += 100
|
|
|
|
|
}
|
|
|
|
|
body = body[2:]
|
|
|
|
|
default:
|
|
|
|
|
if dot := strings.IndexByte(body, '.'); dot >= 0 {
|
|
|
|
|
body, frac = body[:dot], body[dot+1:]
|
|
|
|
|
if frac == "" || frac[len(frac)-1] == '0' || !digits(frac) {
|
|
|
|
|
return time.Time{}, false, bad
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if len(body) != 14 || !digits(body) {
|
|
|
|
|
return time.Time{}, false, bad
|
|
|
|
|
}
|
|
|
|
|
year = atoi(body[:4])
|
|
|
|
|
body = body[4:]
|
|
|
|
|
}
|
|
|
|
|
month, day, hour, minute, second := atoi(body[0:2]), atoi(body[2:4]), atoi(body[4:6]), atoi(body[6:8]), atoi(body[8:10])
|
|
|
|
|
if month < 1 || month > 12 || day < 1 || hour > 23 || minute > 59 || second > 59 ||
|
|
|
|
|
day > time.Date(year, time.Month(month)+1, 0, 0, 0, 0, 0, time.UTC).Day() {
|
|
|
|
|
return time.Time{}, false, errors.New("der: a date or a time that does not exist")
|
|
|
|
|
}
|
|
|
|
|
nanos := 0
|
|
|
|
|
for i := 0; i < 9; i++ {
|
|
|
|
|
nanos *= 10
|
|
|
|
|
if i < len(frac) {
|
|
|
|
|
nanos += int(frac[i] - '0')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return time.Date(year, time.Month(month), day, hour, minute, second, nanos, time.UTC), frac != "", nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func digits(s string) bool {
|
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
|
|
|
if s[i] < '0' || s[i] > '9' {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return s != ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func atoi(s string) int {
|
|
|
|
|
n := 0
|
|
|
|
|
for i := 0; i < len(s); i++ {
|
|
|
|
|
n = n*10 + int(s[i]-'0')
|
|
|
|
|
}
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// header returns the length of the identifier and length octets of the
|
|
|
|
|
// element at the start of b, and the length of its content, which must fit
|
|
|
|
|
// in b.
|
|
|
|
|
func header(b []byte) (headerLen, contentLen int, err error) {
|
|
|
|
|
if len(b) < 2 {
|
|
|
|
|
return 0, 0, errors.New("der: truncated element")
|
|
|
|
|
}
|
|
|
|
|
if b[0]&0x1f == 0x1f {
|
|
|
|
|
return 0, 0, errors.New("der: a tag number of 31 or more")
|
|
|
|
|
}
|
|
|
|
|
l := b[1]
|
|
|
|
|
switch {
|
|
|
|
|
case l < 0x80:
|
|
|
|
|
headerLen, contentLen = 2, int(l)
|
|
|
|
|
case l == 0x80:
|
|
|
|
|
return 0, 0, errors.New("der: an indefinite length")
|
|
|
|
|
case l == 0xff:
|
|
|
|
|
return 0, 0, errors.New("der: a length of 0xff")
|
|
|
|
|
default:
|
|
|
|
|
n := int(l & 0x7f)
|
|
|
|
|
if n > 4 || len(b) < 2+n {
|
|
|
|
|
return 0, 0, errors.New("der: a length that does not fit")
|
|
|
|
|
}
|
|
|
|
|
if b[2] == 0 {
|
|
|
|
|
return 0, 0, errors.New("der: a length with a leading zero")
|
|
|
|
|
}
|
|
|
|
|
v := 0
|
|
|
|
|
for _, c := range b[2 : 2+n] {
|
|
|
|
|
v = v<<8 | int(c)
|
|
|
|
|
}
|
|
|
|
|
if v < 0x80 {
|
|
|
|
|
return 0, 0, errors.New("der: a long form for a length under 128")
|
|
|
|
|
}
|
|
|
|
|
headerLen, contentLen = 2+n, v
|
|
|
|
|
}
|
|
|
|
|
if contentLen < 0 || contentLen > len(b)-headerLen {
|
|
|
|
|
return 0, 0, errors.New("der: an element longer than its container")
|
|
|
|
|
}
|
|
|
|
|
return headerLen, contentLen, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check validates the element at the start of b and returns its length.
|
|
|
|
|
func check(b []byte, depth int) (int, error) {
|
|
|
|
|
if depth > maxDepth {
|
|
|
|
|
return 0, errors.New("der: nested too deep")
|
|
|
|
|
}
|
|
|
|
|
hl, cl, err := header(b)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
content := b[hl : hl+cl]
|
|
|
|
|
id := b[0]
|
|
|
|
|
class, constructed, tag := id>>6, id&0x20 != 0, id&0x1f
|
|
|
|
|
if constructed {
|
|
|
|
|
if class == 0 && tag != 16 && tag != 17 {
|
|
|
|
|
return 0, fmt.Errorf("der: constructed form of the universal type %d", tag)
|
|
|
|
|
}
|
|
|
|
|
for len(content) > 0 {
|
|
|
|
|
n, err := check(content, depth+1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
content = content[n:]
|
|
|
|
|
}
|
|
|
|
|
return hl + cl, nil
|
|
|
|
|
}
|
|
|
|
|
if class == 0 {
|
|
|
|
|
if err := checkPrimitive(tag, content); err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return hl + cl, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func checkPrimitive(tag byte, c []byte) error {
|
|
|
|
|
switch tag {
|
|
|
|
|
case 1: // BOOLEAN
|
|
|
|
|
if len(c) != 1 || (c[0] != 0 && c[0] != 0xff) {
|
|
|
|
|
return errors.New("der: a BOOLEAN that is not 00 or FF")
|
|
|
|
|
}
|
|
|
|
|
case 2, 10: // INTEGER, ENUMERATED
|
|
|
|
|
if len(c) == 0 {
|
|
|
|
|
return errors.New("der: an empty INTEGER")
|
|
|
|
|
}
|
|
|
|
|
if len(c) > 1 && (c[0] == 0 && c[1]&0x80 == 0 || c[0] == 0xff && c[1]&0x80 != 0) {
|
|
|
|
|
return errors.New("der: an INTEGER that is not minimal")
|
|
|
|
|
}
|
|
|
|
|
case 3: // BIT STRING
|
|
|
|
|
if len(c) == 0 || c[0] > 7 || len(c) == 1 && c[0] != 0 {
|
|
|
|
|
return errors.New("der: a malformed BIT STRING")
|
|
|
|
|
}
|
|
|
|
|
if len(c) > 1 && c[0] != 0 && c[len(c)-1]&(1<<c[0]-1) != 0 {
|
|
|
|
|
return errors.New("der: a BIT STRING with unused bits that are not zero")
|
|
|
|
|
}
|
|
|
|
|
case 5: // NULL
|
|
|
|
|
if len(c) != 0 {
|
|
|
|
|
return errors.New("der: a NULL with content")
|
|
|
|
|
}
|
|
|
|
|
case 6: // OBJECT IDENTIFIER
|
|
|
|
|
if len(c) == 0 || c[len(c)-1]&0x80 != 0 {
|
|
|
|
|
return errors.New("der: a malformed OBJECT IDENTIFIER")
|
|
|
|
|
}
|
|
|
|
|
start := true
|
|
|
|
|
for _, x := range c {
|
|
|
|
|
if start && x == 0x80 {
|
|
|
|
|
return errors.New("der: an OBJECT IDENTIFIER with a leading 0x80 in a subidentifier")
|
|
|
|
|
}
|
|
|
|
|
start = x&0x80 == 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>
1 week ago
|
|
|
case 23, 24: // UTCTime, GeneralizedTime
|
|
|
|
|
if _, _, err := parseTime(tag, string(c)); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
DER: the restricted string types are DER, a NumericString among them
der.Check refused the universal types 7, 18, 21, 25 and 27
(ObjectDescriptor, NumericString, VideotexString, GraphicString and
GeneralString), which DER writes primitive with their content as it is
(X.690 10.2). A certificate whose name holds one of them, as the INN of a
Russian certificate or the countryCode3n of X.520, made the whole CMS
signature F1, and a token S2, while spec v0.12 §29.10 asks for DER and reads
the name with its profile: any value, which is no text when it is not of
the five string types. Such a certificate now meets the profile; its value
shows as no text.
REAL, RELATIVE-OID, TIME and the reserved tags stay refused: their DER has
rules of its own, and no certificate, signature or token uses them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
case 4, 7, 12, 18, 19, 20, 21, 22, 25, 26, 27, 28, 30:
|
|
|
|
|
// OCTET STRING, ObjectDescriptor and the restricted character string
|
|
|
|
|
// types: DER writes them primitive (X.690 10.2), with their content as
|
|
|
|
|
// it is. A name may hold any of them, a NumericString among them, as
|
|
|
|
|
// the certificates of some countries do: what is not text decides at
|
|
|
|
|
// the text of the name (spec §29.10), not here.
|
|
|
|
|
case 16, 17:
|
|
|
|
|
return fmt.Errorf("der: the universal type %d in primitive form", tag)
|
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>
1 week ago
|
|
|
default:
|
|
|
|
|
// 0 is the end of contents of BER, and the rest are types that no
|
DER: the restricted string types are DER, a NumericString among them
der.Check refused the universal types 7, 18, 21, 25 and 27
(ObjectDescriptor, NumericString, VideotexString, GraphicString and
GeneralString), which DER writes primitive with their content as it is
(X.690 10.2). A certificate whose name holds one of them, as the INN of a
Russian certificate or the countryCode3n of X.520, made the whole CMS
signature F1, and a token S2, while spec v0.12 §29.10 asks for DER and reads
the name with its profile: any value, which is no text when it is not of
the five string types. Such a certificate now meets the profile; its value
shows as no text.
REAL, RELATIVE-OID, TIME and the reserved tags stay refused: their DER has
rules of its own, and no certificate, signature or token uses them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
|
|
|
// certificate, signature or token of the profile has: REAL,
|
|
|
|
|
// RELATIVE-OID, TIME and the reserved tags, whose DER has rules of its
|
|
|
|
|
// own that this package does not check.
|
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>
1 week ago
|
|
|
return fmt.Errorf("der: the universal type %d, which the profile does not use", tag)
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|