@@ -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 */
493518static const char x509_ce_arc [] = "2.5.29" ;
494519static 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
503537typedef 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 ;
679757error_out :
680- s_free_extensions (extensions_ , cur_num );
758+ s_free_extensions (extensions_ , extensions_num );
681759 return err ;
682760}
683761
0 commit comments