• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

TLS/SSL and crypto library


コミットメタ情報

リビジョン69d9245996088c485072aa4d4e86baec49ccaa80 (tree)
日時2020-08-26 20:04:17
作者Dmitry Belyavskiy <beldmit@gmai...>
コミッターDmitry Belyavskiy

ログメッセージ

RFC 8398: Name constraints validation

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9654)

変更サマリ

差分

--- a/crypto/x509/v3_ncons.c
+++ b/crypto/x509/v3_ncons.c
@@ -17,6 +17,7 @@
1717 #include <openssl/bn.h>
1818
1919 #include "crypto/x509.h"
20+#include "crypto/punycode.h"
2021 #include "ext_dat.h"
2122
2223 DEFINE_STACK_OF(CONF_VALUE)
@@ -38,6 +39,7 @@ static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
3839 static int nc_dn(const X509_NAME *sub, const X509_NAME *nm);
3940 static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
4041 static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
42+static int nc_email_eai(ASN1_UTF8STRING *sub, ASN1_IA5STRING *eml);
4143 static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
4244 static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base);
4345
@@ -459,6 +461,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
459461 {
460462 GENERAL_SUBTREE *sub;
461463 int i, r, match = 0;
464+ /*
465+ * We need to compare not gen->type field but an "effective" type because
466+ * the otherName field may contain EAI email address treated specially
467+ * according to RFC 8398, section 6
468+ */
469+ int effective_type = ((gen->type == GEN_OTHERNAME) &&
470+ (OBJ_obj2nid(gen->d.otherName->type_id) ==
471+ NID_id_on_SmtpUTF8Mailbox)) ? GEN_EMAIL : gen->type;
462472
463473 /*
464474 * Permitted subtrees: if any subtrees exist of matching the type at
@@ -467,7 +477,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
467477
468478 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
469479 sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
470- if (gen->type != sub->base->type)
480+ if (effective_type != sub->base->type)
471481 continue;
472482 if (!nc_minmax_valid(sub))
473483 return X509_V_ERR_SUBTREE_MINMAX;
@@ -490,7 +500,7 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
490500
491501 for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
492502 sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
493- if (gen->type != sub->base->type)
503+ if (effective_type != sub->base->type)
494504 continue;
495505 if (!nc_minmax_valid(sub))
496506 return X509_V_ERR_SUBTREE_MINMAX;
@@ -509,7 +519,14 @@ static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
509519
510520 static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
511521 {
512- switch (base->type) {
522+ switch (gen->type) {
523+ case GEN_OTHERNAME:
524+ /*
525+ * We are here only when we have SmtpUTF8 name,
526+ * so we match the value of othername with base->d.rfc822Name
527+ */
528+ return nc_email_eai(gen->d.otherName->value->value.utf8string,
529+ base->d.rfc822Name);
513530 case GEN_DIRNAME:
514531 return nc_dn(gen->d.directoryName, base->d.directoryName);
515532
@@ -577,13 +594,59 @@ static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
577594
578595 }
579596
597+/*
598+ * This function implements comparison between ASCII/U-label in eml
599+ * and A-label in base according to RFC 8398, section 6.
600+ * Convert base to U-label and ASCII-parts of domain names, for base
601+ * Octet-to-octet comparison of `eml` and `base` hostname parts
602+ * (ASCII-parts should be compared in case-insensitive manner)
603+ */
604+static int nc_email_eai(ASN1_UTF8STRING *eml, ASN1_IA5STRING *base)
605+{
606+ const char *baseptr = (char *)base->data;
607+ const char *emlptr = (char *)eml->data;
608+ const char *emlat = strrchr(emlptr, '@');
609+
610+ char ulabel[256];
611+ size_t size = sizeof(ulabel) - 1;
612+
613+ if (emlat == NULL)
614+ return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
615+
616+ memset(ulabel, 0, sizeof(ulabel));
617+ /* Special case: initial '.' is RHS match */
618+ if (*baseptr == '.') {
619+ ulabel[0] = '.';
620+ size -= 1;
621+ if (ossl_a2ulabel(baseptr, ulabel + 1, &size) <= 0)
622+ return X509_V_ERR_UNSPECIFIED;
623+
624+ if ((size_t)eml->length > size + 1) {
625+ emlptr += eml->length - (size + 1);
626+ if (ia5casecmp(ulabel, emlptr) == 0)
627+ return X509_V_OK;
628+ }
629+ return X509_V_ERR_PERMITTED_VIOLATION;
630+ }
631+
632+ emlptr = emlat + 1;
633+ if (ossl_a2ulabel(baseptr, ulabel, &size) <= 0)
634+ return X509_V_ERR_UNSPECIFIED;
635+ /* Just have hostname left to match: case insensitive */
636+ if (ia5casecmp(ulabel, emlptr))
637+ return X509_V_ERR_PERMITTED_VIOLATION;
638+
639+ return X509_V_OK;
640+
641+}
642+
580643 static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
581644 {
582645 const char *baseptr = (char *)base->data;
583646 const char *emlptr = (char *)eml->data;
584647
585- const char *baseat = strchr(baseptr, '@');
586- const char *emlat = strchr(emlptr, '@');
648+ const char *baseat = strrchr(baseptr, '@');
649+ const char *emlat = strrchr(emlptr, '@');
587650 if (!emlat)
588651 return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
589652 /* Special case: initial '.' is RHS match */