Skip to content

Commit

Permalink
add support for optional flag and update the dictionaries
Browse files Browse the repository at this point in the history
  • Loading branch information
alandekok committed Feb 23, 2025
1 parent 2c8f7f9 commit 002efd0
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 27 deletions.
4 changes: 2 additions & 2 deletions share/dictionary/der/dictionary.common
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ END DirectoryName
DEFINE GeneralSubtree sequence
BEGIN GeneralSubtree
DEFINE base sequence [email protected]
DEFINE minimum integer option=0,has_default
DEFINE minimum integer has_default,option=0,optional
VALUE minimum DEFAULT 0
DEFINE maximum integer option=1
DEFINE maximum integer option=1,optional
END GeneralSubtree

DEFINE Name sequence
Expand Down
6 changes: 3 additions & 3 deletions share/dictionary/der/dictionary.crl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

DEFINE distributionPoint sequence size=1..
BEGIN distributionPoint
DEFINE distributionPointName sequence option=0
DEFINE distributionPointName sequence option=0,optional
BEGIN distributionPointName
ATTRIBUTE fullName 0 group der_type=sequence,sequence_of=choice,[email protected],option
ATTRIBUTE nameRelativeToCRLIssuer 1 sequence option
Expand All @@ -14,7 +14,7 @@ DEFINE RelativeDistinguishedName set [email protected]
END nameRelativeToCRLIssuer
END distributionPointName

DEFINE reasons struct der_type=bitstring,option=1
ATTRIBUTE reasons 1 struct der_type=bitstring,option,optional
BEGIN reasons
MEMBER unused bit[1]
MEMBER keyCompromise bit[1]
Expand All @@ -27,6 +27,6 @@ MEMBER privilegeWithdrawn bit[1]
MEMBER aACompromise bit[1]
END reasons

ATTRIBUTE cRLIssuer 2 group der_type=sequence,sequence_of=choice,[email protected],option
ATTRIBUTE cRLIssuer 2 group der_type=sequence,sequence_of=choice,[email protected],option,optional

END distributionPoint
20 changes: 10 additions & 10 deletions share/dictionary/der/dictionary.extensions
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ ATTRIBUTE basicConstraints 2.5.29.19 sequence is_oid_leaf
BEGIN 2.5.29.19
DEFINE cA boolean has_default
VALUE cA DEFAULT false
DEFINE pathLenConstraint integer
DEFINE pathLenConstraint integer optional
END 2.5.29.19

ATTRIBUTE nameConstraints 2.5.29.30 sequence is_oid_leaf
BEGIN 2.5.29.30
DEFINE permittedSubtrees group [email protected],sequence_of=sequence,option=0
DEFINE excludedSubtrees group [email protected],sequence_of=sequence,option=1
DEFINE permittedSubtrees group [email protected],sequence_of=sequence,option=0,optional
DEFINE excludedSubtrees group [email protected],sequence_of=sequence,option=1,optional
END 2.5.29.30

ATTRIBUTE cRLDIstributionPoints 2.5.29.31 sequence sequence_of=sequence,is_oid_leaf
ATTRIBUTE CRLDIstributionPoints 2.5.29.31 sequence sequence_of=sequence,is_oid_leaf
BEGIN 2.5.29.31
$INCLUDE dictionary.crl
END 2.5.29.31
Expand All @@ -66,7 +66,7 @@ DEFINE policyInformation sequence
BEGIN policyInformation
DEFINE policyIdentifier oid

DEFINE policyQualifiers sequence sequence_of=sequence,size=1..
DEFINE policyQualifiers sequence sequence_of=sequence,size=1..,optional
BEGIN policyQualifiers
DEFINE policyQualifierInfo sequence sequence_of=oid_and_value,[email protected]
END policyQualifiers
Expand All @@ -82,15 +82,15 @@ END 2.5.29.33

ATTRIBUTE authorityKeyIdentifier 2.5.29.35 sequence sequence_of=choice,is_oid_leaf
BEGIN 2.5.29.35
ATTRIBUTE keyIdentifier 0 octetstring option
ATTRIBUTE authorityCertIssuer 1 group der_type=sequence,sequence_of=choice,[email protected],option
ATTRIBUTE authorityCertSerialNumber 2 octetstring option
ATTRIBUTE keyIdentifier 0 octetstring option,optional
ATTRIBUTE authorityCertIssuer 1 group der_type=sequence,sequence_of=choice,[email protected],option,optional
ATTRIBUTE authorityCertSerialNumber 2 octetstring der_type=integer,option,optional
END 2.5.29.35

ATTRIBUTE policyConstraints 2.5.29.36 sequence is_oid_leaf
BEGIN 2.5.29.36
DEFINE requireExplicitPolicy octetstring option=0
DEFINE inhibitPolicyMapping octetstring option=1
DEFINE requireExplicitPolicy octetstring option=0,optional
DEFINE inhibitPolicyMapping octetstring option=1,optional
END 2.5.29.36

ATTRIBUTE extKeyUsage 2.5.29.37 sequence sequence_of=oid,size=1..,is_oid_leaf
Expand Down
4 changes: 2 additions & 2 deletions share/dictionary/der/dictionary.oids
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ ATTRIBUTE qualifier 1.3.6.1.5.5.7.2 choice
ATTRIBUTE cpsuri 1.3.6.1.5.5.7.2.1 ia5string
ATTRIBUTE userNotice 1.3.6.1.5.5.7.2.2 sequence
BEGIN 1.3.6.1.5.5.7.2.2
DEFINE noticeRef sequence
DEFINE noticeRef sequence optional
BEGIN noticeRef
DEFINE displayText string
DEFINE explicitText string optional
DEFINE noticeNumbers sequence sequence_of=integer
BEGIN noticeNumbers
DEFINE number integer
Expand Down
5 changes: 4 additions & 1 deletion share/dictionary/der/dictionary.rfc5280
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ DEFINE algorithm sequence sequence_of=oid_and_value,[email protected]
DEFINE subjectPublicKey bitstring
END subjectPublicKeyInfo

DEFINE extensions x509_extensions [email protected],size=1..
DEFINE issuerUniqueID octetstring option=1,optional
DEFINE subjectUniqueID octetstring option=2,optional

DEFINE extensions x509_extensions [email protected],size=1..,option=3,optional

END tbsCertificate

Expand Down
10 changes: 10 additions & 0 deletions src/protocols/der/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,15 @@ static int dict_flag_option(fr_dict_attr_t **da_p, char const *value, UNUSED fr_
return 0;
}

static int dict_flag_optional(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules)
{
fr_der_attr_flags_t *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);

flags->optional = true;

return 0;
}

static const fr_dict_flag_parser_t der_flags[] = {
// { L("class"), { .func = dict_flag_class } },
{ L("der_type"), { .func = dict_flag_der_type, .needs_value = true } },
Expand All @@ -504,6 +513,7 @@ static const fr_dict_flag_parser_t der_flags[] = {
{ L("is_oid_leaf"), { .func = dict_flag_is_oid_leaf } },
{ L("max"), { .func = dict_flag_max, .needs_value = true } },
{ L("option"), { .func = dict_flag_option} },
{ L("optional"), { .func = dict_flag_optional} },
{ L("sequence_of"), { .func = dict_flag_sequence_of, .needs_value = true } },
{ L("set_of"), { .func = dict_flag_set_of, .needs_value = true } },
{ L("size"), { .func = dict_flag_size, .needs_value=true } },
Expand Down
19 changes: 14 additions & 5 deletions src/protocols/der/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,7 @@ static ssize_t fr_der_decode_hdr(fr_dict_attr_t const *parent, fr_dbuff_t *in, u
fr_der_tag_decode_t *func;
fr_der_tag_class_t tag_class;
fr_der_tag_constructed_t constructed;
fr_der_attr_flags_t const *flags;

FR_DBUFF_OUT_RETURN(&tag_byte, &our_in);

Expand Down Expand Up @@ -1570,20 +1571,26 @@ static ssize_t fr_der_decode_hdr(fr_dict_attr_t const *parent, fr_dbuff_t *in, u
fr_strerror_const("No parent attribute to resolve tag");
return -1;
}
flags = fr_der_attr_flags(parent);

if (tag_class != fr_der_flag_class(parent)) {
if (tag_class != flags->class) {
fr_strerror_printf("Invalid DER class %02x for attribute %s. Expected DER class %02x", *tag, parent->name,
tag_class, fr_der_flag_class(parent));
tag_class, flags->class);
return -1;
}

if (*tag != fr_der_flag_option(parent)) {
/*
* Doesn't match, check if it's optional.
*/
if (*tag != flags->option) {
if (flags->optional) return 0;

fr_strerror_printf("Invalid tag %u for attribute %s. Expected %u", *tag, parent->name,
fr_der_flag_option(parent));
return -1;
}

*tag = fr_der_flag_der_type(parent);
*tag = flags->der_type;
}

if ((*tag >= NUM_ELEMENTS(tag_funcs)) || (*tag == FR_DER_TAG_INVALID)) {
Expand Down Expand Up @@ -2233,7 +2240,9 @@ static ssize_t fr_der_decode_pair_dbuff(TALLOC_CTX *ctx, fr_pair_list_t *out, fr
return fr_dbuff_set(in, &our_in);
}

if (unlikely(fr_der_decode_hdr(parent, &our_in, &tag, &len) <= 0)) {
slen = fr_der_decode_hdr(parent, &our_in, &tag, &len);
if ((slen == 0) && flags->optional) return 0;
if (slen <= 0) {
fr_strerror_const_push("Failed decoding header");
return -1;
}
Expand Down
2 changes: 2 additions & 0 deletions src/protocols/der/der.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ typedef struct {
uint64_t max; //!< maximum count of items in a sequence, set, or string.
uint8_t min; //!< mininum count
uint8_t option; //!< an "attribute number" encoded in the tag field.
bool optional : 1; //!< optional, we MUST already have set 'option'
bool is_sequence_of : 1; //!< sequence_of has been defined
bool is_set_of : 1; //!< set_of has been defined
bool is_pair : 1; //!< is OID+value
Expand All @@ -115,6 +116,7 @@ static inline fr_der_attr_flags_t const *fr_der_attr_flags(fr_dict_attr_t const
}

#define fr_der_flag_option(_da) (fr_der_attr_flags(_da)->option)
#define fr_der_flag_optional(_da) (fr_der_attr_flags(_da)->optional)
#define fr_der_flag_class(_da) (fr_der_attr_flags(_da)->class)
#define fr_der_flag_der_type(_da) (fr_der_attr_flags(_da)->der_type)
#define fr_der_flag_sequence_of(_da) (fr_der_attr_flags(_da)->sequence_of)
Expand Down
2 changes: 1 addition & 1 deletion src/tests/unit/protocols/der/pkcs10.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ decode-pair a3 81 84 30 81 81 30 7f 06 08 2b 06 01 05 05 07 01 01 04 73 30 71 30
match Certificate-Extensions = { iso = { identified-organization = { dod = { internet = { security = { mechanisms = { pkix = { pe = { authorityInfoAccess = { accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.1", accessLocation = { uniformResourceIdentifier = "http://isrg.trustid.ocsp.identrust.com" } }, accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.2", accessLocation = { uniformResourceIdentifier = "http://apps.identrust.com/roots/dstrootcax3.p7c" } } } } } } } } } } } }

decode-pair a3 82 01 7d 30 82 01 79 30 7f 06 08 2b 06 01 05 05 07 01 01 04 73 30 71 30 32 06 08 2b 06 01 05 05 07 30 01 86 26 68 74 74 70 3a 2f 2f 69 73 72 67 2e 74 72 75 73 74 69 64 2e 6f 63 73 70 2e 69 64 65 6e 74 72 75 73 74 2e 63 6f 6d 30 3b 06 08 2b 06 01 05 05 07 30 02 86 2f 68 74 74 70 3a 2f 2f 61 70 70 73 2e 69 64 65 6e 74 72 75 73 74 2e 63 6f 6d 2f 72 6f 6f 74 73 2f 64 73 74 72 6f 6f 74 63 61 78 33 2e 70 37 63 30 1f 06 03 55 1d 23 04 18 30 16 80 14 c4 a7 b1 a4 7b 2c 71 fa db e1 4b 90 75 ff c4 15 60 85 89 10 30 54 06 03 55 1d 20 04 4d 30 4b 30 08 06 06 67 81 0c 01 02 01 30 3f 06 0b 2b 06 01 04 01 82 df 13 01 01 01 30 30 30 2e 06 08 2b 06 01 05 05 07 02 01 16 22 68 74 74 70 3a 2f 2f 63 70 73 2e 72 6f 6f 74 2d 78 31 2e 6c 65 74 73 65 6e 63 72 79 70 74 2e 6f 72 67 30 3c 06 03 55 1d 1f 04 35 30 33 30 31 a0 2f a0 2d 86 2b 68 74 74 70 3a 2f 2f 63 72 6c 2e 69 64 65 6e 74 72 75 73 74 2e 63 6f 6d 2f 44 53 54 52 4f 4f 54 43 41 58 33 43 52 4c 2e 63 72 6c 30 1d 06 03 55 1d 0e 04 16 04 14 a8 4a 6a 63 04 7d dd ba e6 d1 39 b7 a6 45 65 ef f3 a8 ec a1 30 12 06 03 55 1d 13 01 01 ff 04 08 30 06 01 01 ff 02 01 00 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 01 86
match Certificate-Extensions = { Critical = { joint-iso-itu-t = { ds = { certificateExtension = { basicConstraints = { cA = yes, pathLenConstraint = 0 } } } }, joint-iso-itu-t = { ds = { certificateExtension = { keyUsage = { digitalSignature = yes, nonRepudation = no, keyEncipherment = no, dataEncipherment = no, keyAgreement = no, keyCertSign = yes, cRLSign = yes, encipherOnly = no } } } } }, iso = { identified-organization = { dod = { internet = { security = { mechanisms = { pkix = { pe = { authorityInfoAccess = { accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.1", accessLocation = { uniformResourceIdentifier = "http://isrg.trustid.ocsp.identrust.com" } }, accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.2", accessLocation = { uniformResourceIdentifier = "http://apps.identrust.com/roots/dstrootcax3.p7c" } } } } } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { authorityKeyIdentifier = { keyIdentifier = 0xc4a7b1a47b2c71fadbe14b9075ffc41560858910 } } } }, joint-iso-itu-t = { ds = { certificateExtension = { certificatePolicies = { policyInformation = { policyIdentifier = "2.23.140.1.2.1" }, policyInformation = { policyIdentifier = "1.3.6.1.4.1.44947.1.1.1", policyQualifiers = { policyQualifierInfo = { iso = { identified-organization = { dod = { internet = { security = { mechanisms = { pkix = { qualifier = { cpsuri = "http://cps.root-x1.letsencrypt.org" } } } } } } } } } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { cRLDIstributionPoints = { distributionPoint = { distributionPointName = { fullName = { uniformResourceIdentifier = "http://crl.identrust.com/DSTROOTCAX3CRL.crl" } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { subjectKeyIdentifier = 0xa84a6a63047dddbae6d139b7a64565eff3a8eca1 } } } }
match Certificate-Extensions = { Critical = { joint-iso-itu-t = { ds = { certificateExtension = { basicConstraints = { cA = yes, pathLenConstraint = 0 } } } }, joint-iso-itu-t = { ds = { certificateExtension = { keyUsage = { digitalSignature = yes, nonRepudation = no, keyEncipherment = no, dataEncipherment = no, keyAgreement = no, keyCertSign = yes, cRLSign = yes, encipherOnly = no } } } } }, iso = { identified-organization = { dod = { internet = { security = { mechanisms = { pkix = { pe = { authorityInfoAccess = { accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.1", accessLocation = { uniformResourceIdentifier = "http://isrg.trustid.ocsp.identrust.com" } }, accessDescription = { accessMethod = "1.3.6.1.5.5.7.48.2", accessLocation = { uniformResourceIdentifier = "http://apps.identrust.com/roots/dstrootcax3.p7c" } } } } } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { authorityKeyIdentifier = { keyIdentifier = 0xc4a7b1a47b2c71fadbe14b9075ffc41560858910 } } } }, joint-iso-itu-t = { ds = { certificateExtension = { certificatePolicies = { policyInformation = { policyIdentifier = "2.23.140.1.2.1" }, policyInformation = { policyIdentifier = "1.3.6.1.4.1.44947.1.1.1", policyQualifiers = { policyQualifierInfo = { iso = { identified-organization = { dod = { internet = { security = { mechanisms = { pkix = { qualifier = { cpsuri = "http://cps.root-x1.letsencrypt.org" } } } } } } } } } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { CRLDIstributionPoints = { distributionPoint = { distributionPointName = { fullName = { uniformResourceIdentifier = "http://crl.identrust.com/DSTROOTCAX3CRL.crl" } } } } } } }, joint-iso-itu-t = { ds = { certificateExtension = { subjectKeyIdentifier = 0xa84a6a63047dddbae6d139b7a64565eff3a8eca1 } } } }

proto-dictionary der
encode-pair Certificate-Extensions = { iso = { identified-organization = { raw.4 = 0x3071303201 } } }
Expand Down
Loading

0 comments on commit 002efd0

Please sign in to comment.