Skip to content

Commit 257d1c4

Browse files
committed
Add more extensions.
1 parent 5c82093 commit 257d1c4

5 files changed

Lines changed: 154 additions & 27 deletions

File tree

src/headers/tomcrypt_pk.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,16 @@ typedef enum ltc_x509_details {
10761076
LTC_X509_OU,
10771077
/* EmailAddress */
10781078
LTC_X509_EMAIL,
1079+
/* Name */
1080+
LTC_X509_N,
1081+
/* Surname */
1082+
LTC_X509_SN,
1083+
/* GivenName */
1084+
LTC_X509_GN,
1085+
/* Initials */
1086+
LTC_X509_IN,
1087+
/* GenerationQualifier */
1088+
LTC_X509_GQ,
10791089

10801090
/* GeneralName subtypes
10811091
* GeneralName ::= CHOICE {
@@ -1109,12 +1119,30 @@ typedef enum ltc_x509_details {
11091119
LTC_X509_CE_SUBJECT_KEY_ID,
11101120
/* KeyUsage */
11111121
LTC_X509_CE_KEY_USAGE,
1122+
/* CertificatePolicies */
1123+
LTC_X509_CE_CERTIFICATE_POLICIES,
1124+
/* PolicyMappings */
1125+
LTC_X509_CE_POLICY_MAPPINGS,
11121126
/* SubjectAltName */
11131127
LTC_X509_CE_SUBJECT_ALT_NAME,
1128+
/* IssuerAltName */
1129+
LTC_X509_CE_ISSUER_ALT_NAME,
1130+
/* SubjectDirectoryAttributes */
1131+
LTC_X509_CE_SUBJECT_DIRECTORY_ATTRIBUTES,
11141132
/* BasicConstraints */
11151133
LTC_X509_CE_BASIC_CONSTRAINTS,
1134+
/* NameConstraints */
1135+
LTC_X509_CE_NAME_CONSTRAINTS,
1136+
/* PolicyConstraints */
1137+
LTC_X509_CE_POLICY_CONSTRAINTS,
11161138
/* ExtendedKeyUsage */
11171139
LTC_X509_CE_EXT_KEY_USAGE,
1140+
/* CRLDistributionPoints */
1141+
LTC_X509_CE_CRL_DISTRIBUTION_POINTS,
1142+
/* InhibitAnyPolicy */
1143+
LTC_X509_CE_INHIBIT_ANY_POLICY,
1144+
/* FreshestCRL */
1145+
LTC_X509_CE_FRESHEST_CRL,
11181146

11191147
/* The rest will not be decoded and has to be treated
11201148
* manually through the `asn1` pointer of the struct.
@@ -1222,6 +1250,8 @@ typedef struct ltc_x509_extension {
12221250
ulong32 key_usage;
12231251
/* .type = LTC_X509_CE_SUBJECT_ALT_NAME */
12241252
ltc_x509_name subject_alt_name;
1253+
/* .type = LTC_X509_CE_ISSUER_ALT_NAME */
1254+
ltc_x509_name issuer_alt_name;
12251255
/* .type = LTC_X509_CE_BASIC_CONSTRAINTS */
12261256
struct {
12271257
int ca;
@@ -1247,11 +1277,20 @@ typedef struct ltc_x509_extensions {
12471277
const ltc_x509_extension *authority_key_id;
12481278
const ltc_x509_extension *subject_key_identifier;
12491279
const ltc_x509_extension *key_usage;
1280+
const ltc_x509_extension *certificate_policies;
1281+
const ltc_x509_extension *policy_mappings;
12501282
const ltc_x509_extension *subject_alt_name;
1283+
const ltc_x509_extension *issuer_alt_name;
1284+
const ltc_x509_extension *subject_directory_attributes;
12511285
const ltc_x509_extension *basic_constraints;
1286+
const ltc_x509_extension *name_constraints;
1287+
const ltc_x509_extension *policy_constraints;
12521288
const ltc_x509_extension *ext_key_usage;
1289+
const ltc_x509_extension *crl_distribution_points;
1290+
const ltc_x509_extension *inhibit_any_policy;
1291+
const ltc_x509_extension *freshest_crl;
12531292
/* let's pre-reserve this for future extensions */
1254-
const ltc_x509_extension *more[7];
1293+
const ltc_x509_extension *more[10];
12551294
} ltc_x509_extensions;
12561295

12571296
typedef struct ltc_x509_tbs_certificate {

src/pk/asn1/x509/x509_extensions.c

Lines changed: 99 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ static int s_get_aki(const ltc_asn1_list *seq, ltc_x509_extension *aki)
272272
{
273273
int err;
274274
ltc_asn1_list *element = seq->child;
275+
if (aki->critical) {
276+
return CRYPT_PK_ASN1_ERROR;
277+
}
275278
while(element && s_is_context_specific_primitive(element)) {
276279
switch (element->tag) {
277280
case 0:
@@ -310,7 +313,7 @@ static int s_get_ski(const ltc_asn1_list *seq, ltc_x509_extension *ski)
310313
void *buf;
311314
unsigned long len, outlen;
312315
int err;
313-
if (seq->type != LTC_ASN1_OCTET_STRING) {
316+
if (seq->type != LTC_ASN1_OCTET_STRING || ski->critical) {
314317
return CRYPT_PK_ASN1_ERROR;
315318
}
316319
/* `size` still contains the ASN.1 header and length, so we're safe length-wise */
@@ -445,8 +448,11 @@ static int s_get_eku(const ltc_asn1_list *seq, ltc_x509_extension *eku)
445448
* SubjectAltName ::= GeneralNames
446449
*
447450
* GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
451+
*
452+
* RFC 5280, Ch. 4.2.1.7. Issuer Alternative Name
453+
* IssuerAltName ::= GeneralNames
448454
*/
449-
static int s_get_san(const ltc_asn1_list *seq, ltc_x509_extension *san)
455+
static int s_get_xan(const ltc_asn1_list *seq, ltc_x509_extension *san)
450456
{
451457
int err = CRYPT_PK_ASN1_ERROR;
452458
ltc_x509_string *names;
@@ -475,15 +481,34 @@ static int s_get_san(const ltc_asn1_list *seq, ltc_x509_extension *san)
475481
cur++;
476482
}
477483
if (err == CRYPT_OK) {
478-
san->u.subject_alt_name.asn1 = seq;
479-
san->u.subject_alt_name.names = names;
480-
san->u.subject_alt_name.names_num = num;
484+
ltc_x509_name *dest = san->type == LTC_X509_CE_SUBJECT_ALT_NAME ?
485+
&san->u.subject_alt_name : &san->u.issuer_alt_name;
486+
dest->asn1 = seq;
487+
dest->names = names;
488+
dest->names_num = num;
481489
} else {
482490
s_free_x509_string_array(names, cur);
483491
}
484492
return err;
485493
}
486494

495+
/* RFC 5280, Ch. 4.2 Certificate Extensions
496+
* All extensions that are known, but not implemented yet.
497+
*/
498+
static int s_not_implemented_yet(const ltc_asn1_list *seq, ltc_x509_extension *ext)
499+
{
500+
LTC_UNUSED_PARAM(seq);
501+
LTC_UNUSED_PARAM(ext);
502+
return CRYPT_OK;
503+
}
504+
505+
static int s_not_implemented_yet_crit(const ltc_asn1_list *seq, ltc_x509_extension *ext)
506+
{
507+
LTC_UNUSED_PARAM(seq);
508+
LTC_UNUSED_PARAM(ext);
509+
return ext->critical ? CRYPT_PK_ASN1_ERROR : CRYPT_OK;
510+
}
511+
487512
#define X509_CE_ELEMENT(detail, oid, type_, hndl) OID_DETAIL_ELEMENT_VA(detail, oid, .u.ce.type = type_, .u.ce.handler = (der_flexi_handler)hndl)
488513

489514
/* The certificate extension OID's arc is defined as follows
@@ -492,12 +517,21 @@ static int s_get_san(const ltc_asn1_list *seq, ltc_x509_extension *san)
492517
*/
493518
static const char x509_ce_arc[] = "2.5.29";
494519
static const st_oid_detail ce_elements_map[] = {
495-
X509_CE_ELEMENT(LTC_X509_CE_AUTHORITY_KEY_ID, 35, LTC_ASN1_SEQUENCE, s_get_aki),
496-
X509_CE_ELEMENT(LTC_X509_CE_SUBJECT_KEY_ID, 14, LTC_ASN1_OCTET_STRING, s_get_ski),
497-
X509_CE_ELEMENT(LTC_X509_CE_KEY_USAGE, 15, LTC_ASN1_BIT_STRING, s_get_ku),
498-
X509_CE_ELEMENT(LTC_X509_CE_SUBJECT_ALT_NAME, 17, LTC_ASN1_SEQUENCE, s_get_san),
499-
X509_CE_ELEMENT(LTC_X509_CE_BASIC_CONSTRAINTS, 19, LTC_ASN1_SEQUENCE, s_get_bc),
500-
X509_CE_ELEMENT(LTC_X509_CE_EXT_KEY_USAGE, 37, LTC_ASN1_SEQUENCE, s_get_eku),
520+
X509_CE_ELEMENT(LTC_X509_CE_AUTHORITY_KEY_ID, 35, LTC_ASN1_SEQUENCE, s_get_aki),
521+
X509_CE_ELEMENT(LTC_X509_CE_SUBJECT_KEY_ID, 14, LTC_ASN1_OCTET_STRING, s_get_ski),
522+
X509_CE_ELEMENT(LTC_X509_CE_KEY_USAGE, 15, LTC_ASN1_BIT_STRING, s_get_ku),
523+
X509_CE_ELEMENT(LTC_X509_CE_CERTIFICATE_POLICIES, 32, LTC_ASN1_SEQUENCE, s_not_implemented_yet_crit),
524+
X509_CE_ELEMENT(LTC_X509_CE_POLICY_MAPPINGS, 33, LTC_ASN1_SEQUENCE, s_not_implemented_yet),
525+
X509_CE_ELEMENT(LTC_X509_CE_SUBJECT_ALT_NAME, 17, LTC_ASN1_SEQUENCE, s_get_xan),
526+
X509_CE_ELEMENT(LTC_X509_CE_ISSUER_ALT_NAME, 18, LTC_ASN1_SEQUENCE, s_get_xan),
527+
X509_CE_ELEMENT(LTC_X509_CE_SUBJECT_DIRECTORY_ATTRIBUTES, 9, LTC_ASN1_SEQUENCE, s_not_implemented_yet_crit),
528+
X509_CE_ELEMENT(LTC_X509_CE_BASIC_CONSTRAINTS, 19, LTC_ASN1_SEQUENCE, s_get_bc),
529+
X509_CE_ELEMENT(LTC_X509_CE_NAME_CONSTRAINTS, 30, LTC_ASN1_SEQUENCE, s_not_implemented_yet),
530+
X509_CE_ELEMENT(LTC_X509_CE_POLICY_CONSTRAINTS, 36, LTC_ASN1_SEQUENCE, s_not_implemented_yet),
531+
X509_CE_ELEMENT(LTC_X509_CE_EXT_KEY_USAGE, 37, LTC_ASN1_SEQUENCE, s_get_eku),
532+
X509_CE_ELEMENT(LTC_X509_CE_CRL_DISTRIBUTION_POINTS, 31, LTC_ASN1_SEQUENCE, s_not_implemented_yet),
533+
X509_CE_ELEMENT(LTC_X509_CE_INHIBIT_ANY_POLICY, 54, LTC_ASN1_INTEGER, s_not_implemented_yet),
534+
X509_CE_ELEMENT(LTC_X509_CE_FRESHEST_CRL, 46, LTC_ASN1_INTEGER, s_not_implemented_yet),
501535
};
502536

503537
typedef struct st_ce_value {
@@ -563,9 +597,9 @@ static LTC_INLINE void s_free_extension(const ltc_x509_extension *ext)
563597
case LTC_X509_CE_SUBJECT_ALT_NAME:
564598
s_free_x509_string_array(ext->u.subject_alt_name.names, ext->u.subject_alt_name.names_num);
565599
break;
566-
case LTC_X509_CE_BASIC_CONSTRAINTS:
567-
case LTC_X509_CE_EXT_KEY_USAGE:
568-
case LTC_X509_CE_KEY_USAGE:
600+
case LTC_X509_CE_ISSUER_ALT_NAME:
601+
s_free_x509_string_array(ext->u.issuer_alt_name.names, ext->u.issuer_alt_name.names_num);
602+
break;
569603
default:
570604
break;
571605
}
@@ -644,24 +678,65 @@ int x509_get_extensions(const ltc_asn1_list *seq, ltc_x509_extensions *extension
644678
cur = cur->next;
645679
}
646680
for (cur_num = 0; cur_num < extensions_num; ++cur_num) {
681+
682+
/* RFC 5280, Ch. 4.2. Certificate Extensions
683+
* [...]
684+
* A certificate MUST NOT include more than one instance of a particular extension.
685+
* [...]
686+
*/
687+
#define set_extension(target, source) do { \
688+
if ((target) != NULL) { \
689+
err = CRYPT_PK_ASN1_ERROR; \
690+
goto error_out; \
691+
} \
692+
(target) = (source); \
693+
} while(0)
694+
647695
switch (extensions_[cur_num].type) {
648696
case LTC_X509_CE_AUTHORITY_KEY_ID:
649-
extensions->authority_key_id = &extensions_[cur_num];
697+
set_extension(extensions->authority_key_id, &extensions_[cur_num]);
650698
break;
651699
case LTC_X509_CE_SUBJECT_KEY_ID:
652-
extensions->subject_key_identifier = &extensions_[cur_num];
700+
set_extension(extensions->subject_key_identifier, &extensions_[cur_num]);
653701
break;
654702
case LTC_X509_CE_KEY_USAGE:
655-
extensions->key_usage = &extensions_[cur_num];
703+
set_extension(extensions->key_usage, &extensions_[cur_num]);
704+
break;
705+
case LTC_X509_CE_CERTIFICATE_POLICIES:
706+
set_extension(extensions->certificate_policies, &extensions_[cur_num]);
707+
break;
708+
case LTC_X509_CE_POLICY_MAPPINGS:
709+
set_extension(extensions->policy_mappings, &extensions_[cur_num]);
656710
break;
657711
case LTC_X509_CE_SUBJECT_ALT_NAME:
658-
extensions->subject_alt_name = &extensions_[cur_num];
712+
set_extension(extensions->subject_alt_name, &extensions_[cur_num]);
713+
break;
714+
case LTC_X509_CE_ISSUER_ALT_NAME:
715+
set_extension(extensions->issuer_alt_name, &extensions_[cur_num]);
716+
break;
717+
case LTC_X509_CE_SUBJECT_DIRECTORY_ATTRIBUTES:
718+
set_extension(extensions->subject_directory_attributes, &extensions_[cur_num]);
659719
break;
660720
case LTC_X509_CE_BASIC_CONSTRAINTS:
661-
extensions->basic_constraints = &extensions_[cur_num];
721+
set_extension(extensions->basic_constraints, &extensions_[cur_num]);
722+
break;
723+
case LTC_X509_CE_NAME_CONSTRAINTS:
724+
set_extension(extensions->name_constraints, &extensions_[cur_num]);
725+
break;
726+
case LTC_X509_CE_POLICY_CONSTRAINTS:
727+
set_extension(extensions->policy_constraints, &extensions_[cur_num]);
662728
break;
663729
case LTC_X509_CE_EXT_KEY_USAGE:
664-
extensions->ext_key_usage = &extensions_[cur_num];
730+
set_extension(extensions->ext_key_usage, &extensions_[cur_num]);
731+
break;
732+
case LTC_X509_CE_CRL_DISTRIBUTION_POINTS:
733+
set_extension(extensions->crl_distribution_points, &extensions_[cur_num]);
734+
break;
735+
case LTC_X509_CE_INHIBIT_ANY_POLICY:
736+
set_extension(extensions->inhibit_any_policy, &extensions_[cur_num]);
737+
break;
738+
case LTC_X509_CE_FRESHEST_CRL:
739+
set_extension(extensions->freshest_crl, &extensions_[cur_num]);
665740
break;
666741
default:
667742
/* TODO: RFC 5280 4.2 requires rejecting certs with unrecognized critical extensions
@@ -671,13 +746,16 @@ int x509_get_extensions(const ltc_asn1_list *seq, ltc_x509_extensions *extension
671746
*/
672747
break;
673748
}
749+
750+
#undef set_extension
751+
674752
}
675753
extensions->asn1 = seq;
676754
extensions->extensions = extensions_;
677755
extensions->extensions_num = cur_num;
678756
return CRYPT_OK;
679757
error_out:
680-
s_free_extensions(extensions_, cur_num);
758+
s_free_extensions(extensions_, extensions_num);
681759
return err;
682760
}
683761

src/pk/asn1/x509/x509_import.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ typedef struct st_oid_detail {
3434
#define X509_NAME_ELEMENT(detail, oid, ub) OID_DETAIL_ELEMENT_5(detail, X509_NAME_ARC, oid, ASN1_STRING, ub)
3535

3636
static const st_oid_detail name_elements_map[] = {
37-
X509_NAME_ELEMENT(LTC_X509_CN, 3, 64),
38-
X509_NAME_ELEMENT(LTC_X509_C, 6, 2),
39-
X509_NAME_ELEMENT(LTC_X509_L, 7, 128),
40-
X509_NAME_ELEMENT(LTC_X509_ST, 8, 128),
37+
X509_NAME_ELEMENT(LTC_X509_CN, 3, 64),
38+
X509_NAME_ELEMENT(LTC_X509_SN, 4, 32768),
39+
X509_NAME_ELEMENT(LTC_X509_C, 6, 2),
40+
X509_NAME_ELEMENT(LTC_X509_L, 7, 128),
41+
X509_NAME_ELEMENT(LTC_X509_ST, 8, 128),
4142
X509_NAME_ELEMENT(LTC_X509_O, 10, 64),
4243
X509_NAME_ELEMENT(LTC_X509_OU, 11, 64),
44+
X509_NAME_ELEMENT(LTC_X509_N, 41, 32768),
45+
X509_NAME_ELEMENT(LTC_X509_GN, 42, 32768),
46+
X509_NAME_ELEMENT(LTC_X509_IN, 43, 32768),
47+
X509_NAME_ELEMENT(LTC_X509_GQ, 44, 32768),
4348
OID_DETAIL_ELEMENT(LTC_X509_EMAIL, "1.2.840.113549.1.9.1", ASN1_IA5_STRING, 255),
4449
};
4550

src/pk/asn1/x509/x509_utils.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,13 @@ const char *x509_name_detail_desc(ltc_x509_details type)
194194
"Organisation",
195195
"OrganisationalUnit",
196196
"EmailAddress",
197+
"Name",
198+
"Surname",
199+
"GivenName",
200+
"Initials",
201+
"GenerationQualifier",
197202
};
198-
if (type <= LTC_X509_EMAIL) {
203+
if (type <= LTC_X509_GQ) {
199204
return standard_attributes[type];
200205
}
201206
return "Unknown";

0 commit comments

Comments
 (0)