Strengthen X509_STORE_CTX_print_verify_cb() to print expected host etc.
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Thu, 30 Apr 2020 17:31:07 +0000 (19:31 +0200)
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>
Tue, 5 May 2020 08:27:28 +0000 (10:27 +0200)
Add X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(),
and X509_VERIFY_PARAM_get1_ip_asc() to support this,
as well as the internal helper function ipaddr_to_asc(), which
is used also for simplifying other IP address output functions.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/11693)

crypto/x509/t_x509.c
crypto/x509/v3_addr.c
crypto/x509/v3_alt.c
crypto/x509/v3_ncons.c
crypto/x509/v3_utl.c
crypto/x509/x509_vpm.c
doc/man3/X509_VERIFY_PARAM_set_flags.pod
include/internal/cryptlib.h
include/openssl/x509_vfy.h
util/libcrypto.num

index e3c21b084df3ed06773efcef8e142c66d1988175..75d688c50e70e803a4ed7182d92bba06245824b8 100644 (file)
@@ -452,17 +452,46 @@ int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx)
 {
     if (ok == 0 && ctx != NULL) {
         int cert_error = X509_STORE_CTX_get_error(ctx);
 {
     if (ok == 0 && ctx != NULL) {
         int cert_error = X509_STORE_CTX_get_error(ctx);
-        int depth = X509_STORE_CTX_get_error_depth(ctx);
-        X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
         BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
 
         BIO *bio = BIO_new(BIO_s_mem()); /* may be NULL */
 
-        BIO_printf(bio, "%s at depth=%d error=%d (%s)\n",
+        BIO_printf(bio, "%s at depth = %d error = %d (%s)\n",
                    X509_STORE_CTX_get0_parent_ctx(ctx) != NULL
                    X509_STORE_CTX_get0_parent_ctx(ctx) != NULL
-                   ? "CRL path validation" : "certificate verification",
-                   depth, cert_error,
-                   X509_verify_cert_error_string(cert_error));
-        BIO_printf(bio, "failure for:\n");
-        x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS);
+                   ? "CRL path validation"
+                   : "Certificate verification",
+                   X509_STORE_CTX_get_error_depth(ctx),
+                   cert_error, X509_verify_cert_error_string(cert_error));
+        {
+            X509_STORE *ts = X509_STORE_CTX_get0_store(ctx);
+            X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts);
+            char *str;
+            int idx = 0;
+
+            switch (cert_error) {
+            case X509_V_ERR_HOSTNAME_MISMATCH:
+                BIO_printf(bio, "Expected hostname(s) = ");
+                while ((str = X509_VERIFY_PARAM_get0_host(vpm, idx++)) != NULL)
+                    BIO_printf(bio, "%s%s", idx == 1 ? "" : ", ", str);
+                BIO_printf(bio, "\n");
+                break;
+            case X509_V_ERR_EMAIL_MISMATCH:
+                str = X509_VERIFY_PARAM_get0_email(vpm);
+                if (str != NULL)
+                    BIO_printf(bio, "Expected email address = %s\n", str);
+                break;
+            case X509_V_ERR_IP_ADDRESS_MISMATCH:
+                str = X509_VERIFY_PARAM_get1_ip_asc(vpm);
+                if (str != NULL)
+                    BIO_printf(bio, "Expected IP address = %s\n", str);
+                OPENSSL_free(str);
+                break;
+            default:
+                break;
+            }
+        }
+
+        BIO_printf(bio, "Failure for:\n");
+        x509_print_ex_brief(bio, X509_STORE_CTX_get_current_cert(ctx),
+                            X509_FLAG_NO_EXTENSIONS);
         if (cert_error == X509_V_ERR_CERT_UNTRUSTED
                 || cert_error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
                 || cert_error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
         if (cert_error == X509_V_ERR_CERT_UNTRUSTED
                 || cert_error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
                 || cert_error == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
@@ -470,9 +499,9 @@ int X509_STORE_CTX_print_verify_cb(int ok, X509_STORE_CTX *ctx)
                 || cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
                 || cert_error == X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
                 || cert_error == X509_V_ERR_STORE_LOOKUP) {
                 || cert_error == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
                 || cert_error == X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER
                 || cert_error == X509_V_ERR_STORE_LOOKUP) {
-            BIO_printf(bio, "non-trusted certs:\n");
+            BIO_printf(bio, "Non-trusted certs:\n");
             print_certs(bio, X509_STORE_CTX_get0_untrusted(ctx));
             print_certs(bio, X509_STORE_CTX_get0_untrusted(ctx));
-            BIO_printf(bio, "certs in trust store:\n");
+            BIO_printf(bio, "Certs in trust store:\n");
             print_store_certs(bio, X509_STORE_CTX_get0_store(ctx));
         }
         X509err(0, X509_R_CERTIFICATE_VERIFICATION_FAILED);
             print_store_certs(bio, X509_STORE_CTX_get0_store(ctx));
         }
         X509err(0, X509_R_CERTIFICATE_VERIFICATION_FAILED);
index 51f5cd8fa9bbfff2836db2661a528850ef871aff..943423f301fce942a984c572b5cac7d802db7a23 100644 (file)
@@ -144,6 +144,7 @@ static int i2r_address(BIO *out,
             return 0;
         BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
         break;
             return 0;
         BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
         break;
+        /* TODO possibly combine with ipaddr_to_asc() */
     case IANA_AFI_IPV6:
         if (!addr_expand(addr, bs, 16, fill))
             return 0;
     case IANA_AFI_IPV6:
         if (!addr_expand(addr, bs, 16, fill))
             return 0;
index 98ff0bca948c3bada54d5b3e1aeb8b5b3a5deb92..45f7bac27123e19214baf14b257c38bba9e6a882 100644 (file)
@@ -82,10 +82,8 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
                                        GENERAL_NAME *gen,
                                        STACK_OF(CONF_VALUE) *ret)
 {
                                        GENERAL_NAME *gen,
                                        STACK_OF(CONF_VALUE) *ret)
 {
-    unsigned char *p;
     char othername[300];
     char othername[300];
-    char oline[256], htmp[5];
-    int i;
+    char oline[256], *tmp;
 
     switch (gen->type) {
     case GEN_OTHERNAME:
 
     switch (gen->type) {
     case GEN_OTHERNAME:
@@ -183,26 +181,10 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
         break;
 
     case GEN_IPADD:
         break;
 
     case GEN_IPADD:
-        p = gen->d.ip->data;
-        if (gen->d.ip->length == 4)
-            BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d",
-                         p[0], p[1], p[2], p[3]);
-        else if (gen->d.ip->length == 16) {
-            oline[0] = 0;
-            for (i = 0; i < 8; i++) {
-                BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]);
-                p += 2;
-                strcat(oline, htmp);
-                if (i != 7)
-                    strcat(oline, ":");
-            }
-        } else {
-            if (!X509V3_add_value("IP Address", "<invalid>", &ret))
-                return NULL;
-            break;
-        }
-        if (!X509V3_add_value("IP Address", oline, &ret))
-            return NULL;
+        tmp = ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length);
+        if (tmp == NULL || !X509V3_add_value("IP Address", tmp, &ret))
+            ret = NULL;
+        OPENSSL_free(tmp);
         break;
 
     case GEN_RID:
         break;
 
     case GEN_RID:
@@ -216,8 +198,8 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
 
 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
 {
 
 int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
 {
-    unsigned char *p;
-    int i, nid;
+    char *tmp;
+    int nid;
 
     switch (gen->type) {
     case GEN_OTHERNAME:
 
     switch (gen->type) {
     case GEN_OTHERNAME:
@@ -288,19 +270,11 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
         break;
 
     case GEN_IPADD:
         break;
 
     case GEN_IPADD:
-        p = gen->d.ip->data;
-        if (gen->d.ip->length == 4)
-            BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
-        else if (gen->d.ip->length == 16) {
-            BIO_printf(out, "IP Address");
-            for (i = 0; i < 8; i++) {
-                BIO_printf(out, ":%X", p[0] << 8 | p[1]);
-                p += 2;
-            }
-        } else {
-            BIO_printf(out, "IP Address:<invalid>");
-            break;
-        }
+        tmp = ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length);
+        if (tmp == NULL)
+            return 0;
+        BIO_printf(out, "IP Address:%s", tmp);
+        OPENSSL_free(tmp);
         break;
 
     case GEN_RID:
         break;
 
     case GEN_RID:
index 88ad8ba74f065a078fee6e60638542ecf14dca39..d7b82b775e91f4a8b134f1f206d970f2a31cd5bd 100644 (file)
@@ -192,26 +192,17 @@ static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
 
 static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
 {
 
 static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
 {
-    int i, len;
-    unsigned char *p;
-    p = ip->data;
-    len = ip->length;
-    BIO_puts(bp, "IP:");
-    if (len == 8) {
-        BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
-                   p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-    } else if (len == 32) {
-        for (i = 0; i < 16; i++) {
-            BIO_printf(bp, "%X", p[0] << 8 | p[1]);
-            p += 2;
-            if (i == 7)
-                BIO_puts(bp, "/");
-            else if (i != 15)
-                BIO_puts(bp, ":");
-        }
-    } else
-        BIO_printf(bp, "IP Address:<invalid>");
-    return 1;
+    /* ip->length should be 8 or 32 and len1 == len2 == 4 or len1 == len2 == 16 */
+    int len1 = ip->length >= 16 ? 16 : ip->length >= 4 ? 4 : ip->length;
+    int len2 = ip->length - len1;
+    char *ip1 = ipaddr_to_asc(ip->data, len1);
+    char *ip2 = ipaddr_to_asc(ip->data + len1, len2);
+    int ret = ret = ip1 != NULL && ip2 != NULL
+        && BIO_printf(bp, "IP:%s/%s", ip1, ip2) > 0;
+
+    OPENSSL_free(ip1);
+    OPENSSL_free(ip2);
+    return ret;
 }
 
 #define NAME_CHECK_MAX (1 << 20)
 }
 
 #define NAME_CHECK_MAX (1 << 20)
index 4be395397cd38e2e20d7310cf1ab7d30e95367b7..aefb5897430bdb83b10a79dffb4360757ad9d0fc 100644 (file)
@@ -31,7 +31,8 @@ static int sk_strcmp(const char *const *a, const char *const *b);
 static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name,
                                            GENERAL_NAMES *gens);
 static void str_free(OPENSSL_STRING str);
 static STACK_OF(OPENSSL_STRING) *get_email(const X509_NAME *name,
                                            GENERAL_NAMES *gens);
 static void str_free(OPENSSL_STRING str);
-static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email);
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk,
+                      const ASN1_IA5STRING *email);
 
 static int ipv4_from_asc(unsigned char *v4, const char *in);
 static int ipv6_from_asc(unsigned char *v6, const char *in);
 
 static int ipv4_from_asc(unsigned char *v4, const char *in);
 static int ipv6_from_asc(unsigned char *v6, const char *in);
@@ -178,6 +179,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
     ASN1_INTEGER *aint;
     int isneg, ishex;
     int ret;
     ASN1_INTEGER *aint;
     int isneg, ishex;
     int ret;
+
     if (value == NULL) {
         X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
         return NULL;
     if (value == NULL) {
         X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
         return NULL;
@@ -190,14 +192,16 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
     if (value[0] == '-') {
         value++;
         isneg = 1;
     if (value[0] == '-') {
         value++;
         isneg = 1;
-    } else
+    } else {
         isneg = 0;
         isneg = 0;
+    }
 
     if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
         value += 2;
         ishex = 1;
 
     if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
         value += 2;
         ishex = 1;
-    } else
+    } else {
         ishex = 0;
         ishex = 0;
+    }
 
     if (ishex)
         ret = BN_hex2bn(&bn, value);
 
     if (ishex)
         ret = BN_hex2bn(&bn, value);
@@ -297,6 +301,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
     STACK_OF(CONF_VALUE) *values = NULL;
     char *linebuf;
     int state;
     STACK_OF(CONF_VALUE) *values = NULL;
     char *linebuf;
     int state;
+
     /* We are going to modify the line so copy it first */
     linebuf = OPENSSL_strdup(line);
     if (linebuf == NULL) {
     /* We are going to modify the line so copy it first */
     linebuf = OPENSSL_strdup(line);
     if (linebuf == NULL) {
@@ -382,6 +387,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
 static char *strip_spaces(char *name)
 {
     char *p, *q;
 static char *strip_spaces(char *name)
 {
     char *p, *q;
+
     /* Skip over leading spaces */
     p = name;
     while (*p && ossl_isspace(*p))
     /* Skip over leading spaces */
     p = name;
     while (*p && ossl_isspace(*p))
@@ -407,6 +413,7 @@ int v3_name_cmp(const char *name, const char *cmp)
 {
     int len, ret;
     char c;
 {
     int len, ret;
     char c;
+
     len = strlen(cmp);
     if ((ret = strncmp(name, cmp, len)))
         return ret;
     len = strlen(cmp);
     if ((ret = strncmp(name, cmp, len)))
         return ret;
@@ -502,9 +509,11 @@ static void str_free(OPENSSL_STRING str)
     OPENSSL_free(str);
 }
 
     OPENSSL_free(str);
 }
 
-static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email)
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk,
+                      const ASN1_IA5STRING *email)
 {
     char *emtmp;
 {
     char *emtmp;
+
     /* First some sanity checks */
     if (email->type != V_ASN1_IA5STRING)
         return 1;
     /* First some sanity checks */
     if (email->type != V_ASN1_IA5STRING)
         return 1;
@@ -519,7 +528,7 @@ static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email
         return 1;
     emtmp = OPENSSL_strdup((char *)email->data);
     if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
         return 1;
     emtmp = OPENSSL_strdup((char *)email->data);
     if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
-        OPENSSL_free(emtmp);    /* free on push failure */
+        OPENSSL_free(emtmp); /* free on push failure */
         X509_email_free(*sk);
         *sk = NULL;
         return 0;
         X509_email_free(*sk);
         *sk = NULL;
         return 0;
@@ -576,9 +585,10 @@ static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
     skip_prefix(&pattern, &pattern_len, subject_len, flags);
     if (pattern_len != subject_len)
         return 0;
     skip_prefix(&pattern, &pattern_len, subject_len, flags);
     if (pattern_len != subject_len)
         return 0;
-    while (pattern_len) {
+    while (pattern_len != 0) {
         unsigned char l = *pattern;
         unsigned char r = *subject;
         unsigned char l = *pattern;
         unsigned char r = *subject;
+
         /* The pattern must not contain NUL characters. */
         if (l == 0)
             return 0;
         /* The pattern must not contain NUL characters. */
         if (l == 0)
             return 0;
@@ -617,6 +627,7 @@ static int equal_email(const unsigned char *a, size_t a_len,
                        unsigned int unused_flags)
 {
     size_t i = a_len;
                        unsigned int unused_flags)
 {
     size_t i = a_len;
+
     if (a_len != b_len)
         return 0;
     /*
     if (a_len != b_len)
         return 0;
     /*
@@ -704,6 +715,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len,
     size_t i;
     int state = LABEL_START;
     int dots = 0;
     size_t i;
     int state = LABEL_START;
     int dots = 0;
+
     for (i = 0; i < len; ++i) {
         /*
          * Locate first and only legal wildcard, either at the start
     for (i = 0; i < len; ++i) {
         /*
          * Locate first and only legal wildcard, either at the start
@@ -745,8 +757,9 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len,
             if ((state & LABEL_START) != 0)
                 return NULL;
             state |= LABEL_HYPHEN;
             if ((state & LABEL_START) != 0)
                 return NULL;
             state |= LABEL_HYPHEN;
-        } else
+        } else {
             return NULL;
             return NULL;
+        }
     }
 
     /*
     }
 
     /*
@@ -862,6 +875,7 @@ static int do_x509_check(X509 *x, const char *chk, size_t chklen,
         for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
             GENERAL_NAME *gen;
             ASN1_STRING *cstr;
         for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
             GENERAL_NAME *gen;
             ASN1_STRING *cstr;
+
             gen = sk_GENERAL_NAME_value(gens, i);
             if (gen->type != check_type)
                 continue;
             gen = sk_GENERAL_NAME_value(gens, i);
             if (gen->type != check_type)
                 continue;
@@ -961,6 +975,29 @@ int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
     return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
 }
 
     return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
 }
 
+char *ipaddr_to_asc(unsigned char *p, int len)
+{
+    char buf[40], *out;
+
+    switch (len) {
+    case 4: /* IPv4 */
+        BIO_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+        break;
+        /* TODO possibly combine with static i2r_address() in v3_addr.c */
+    case 16: /* IPv6 */
+        for (out = buf; out < buf + 8 * 3; out += 3) {
+            BIO_snprintf(out, 3 + 1, "%X:", p[0] << 8 | p[1]);
+            p += 2;
+        }
+        out[-1] = '\0';
+        break;
+    default:
+        BIO_snprintf(buf, sizeof(buf), "<invalid length=%d>", len);
+        break;
+    }
+    return OPENSSL_strdup(buf);
+}
+
 /*
  * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
  * with RFC3280.
 /*
  * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
  * with RFC3280.
@@ -1050,6 +1087,7 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc)
 static int ipv4_from_asc(unsigned char *v4, const char *in)
 {
     int a0, a1, a2, a3;
 static int ipv4_from_asc(unsigned char *v4, const char *in)
 {
     int a0, a1, a2, a3;
+
     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
         return 0;
     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
         return 0;
     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
@@ -1076,6 +1114,7 @@ typedef struct {
 static int ipv6_from_asc(unsigned char *v6, const char *in)
 {
     IPV6_STAT v6stat;
 static int ipv6_from_asc(unsigned char *v6, const char *in)
 {
     IPV6_STAT v6stat;
+
     v6stat.total = 0;
     v6stat.zero_pos = -1;
     v6stat.zero_cnt = 0;
     v6stat.total = 0;
     v6stat.zero_pos = -1;
     v6stat.zero_cnt = 0;
@@ -1098,21 +1137,19 @@ static int ipv6_from_asc(unsigned char *v6, const char *in)
         if (v6stat.total == 16)
             return 0;
         /* More than three zeroes is an error */
         if (v6stat.total == 16)
             return 0;
         /* More than three zeroes is an error */
-        if (v6stat.zero_cnt > 3)
+        if (v6stat.zero_cnt > 3) {
             return 0;
         /* Can only have three zeroes if nothing else present */
             return 0;
         /* Can only have three zeroes if nothing else present */
-        else if (v6stat.zero_cnt == 3) {
+        else if (v6stat.zero_cnt == 3) {
             if (v6stat.total > 0)
                 return 0;
             if (v6stat.total > 0)
                 return 0;
-        }
-        /* Can only have two zeroes if at start or end */
-        else if (v6stat.zero_cnt == 2) {
+        } else if (v6stat.zero_cnt == 2) {
+            /* Can only have two zeroes if at start or end */
             if ((v6stat.zero_pos != 0)
                 && (v6stat.zero_pos != v6stat.total))
                 return 0;
             if ((v6stat.zero_pos != 0)
                 && (v6stat.zero_pos != v6stat.total))
                 return 0;
-        } else
+        } else {
             /* Can only have one zero if *not* start or end */
             /* Can only have one zero if *not* start or end */
-        {
             if ((v6stat.zero_pos == 0)
                 || (v6stat.zero_pos == v6stat.total))
                 return 0;
             if ((v6stat.zero_pos == 0)
                 || (v6stat.zero_pos == v6stat.total))
                 return 0;
@@ -1131,8 +1168,9 @@ static int ipv6_from_asc(unsigned char *v6, const char *in)
             memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
                    v6stat.tmp + v6stat.zero_pos,
                    v6stat.total - v6stat.zero_pos);
             memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
                    v6stat.tmp + v6stat.zero_pos,
                    v6stat.total - v6stat.zero_pos);
-    } else
+    } else {
         memcpy(v6, v6stat.tmp, 16);
         memcpy(v6, v6stat.tmp, 16);
+    }
 
     return 1;
 }
 
     return 1;
 }
@@ -1140,6 +1178,7 @@ static int ipv6_from_asc(unsigned char *v6, const char *in)
 static int ipv6_cb(const char *elem, int len, void *usr)
 {
     IPV6_STAT *s = usr;
 static int ipv6_cb(const char *elem, int len, void *usr)
 {
     IPV6_STAT *s = usr;
+
     /* Error if 16 bytes written */
     if (s->total == 16)
         return 0;
     /* Error if 16 bytes written */
     if (s->total == 16)
         return 0;
@@ -1203,6 +1242,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
     CONF_VALUE *v;
     int i, mval, spec_char, plus_char;
     char *p, *type;
     CONF_VALUE *v;
     int i, mval, spec_char, plus_char;
     char *p, *type;
+
     if (!nm)
         return 0;
 
     if (!nm)
         return 0;
 
@@ -1217,7 +1257,7 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
             spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
 #else
             spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
             spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
 #else
             spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
-                    || (*p == os_toascii['.']));
+                         || (*p == os_toascii['.']));
 #endif
             if (spec_char) {
                 p++;
 #endif
             if (spec_char) {
                 p++;
@@ -1234,8 +1274,9 @@ int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
         if (plus_char) {
             mval = -1;
             type++;
         if (plus_char) {
             mval = -1;
             type++;
-        } else
+        } else {
             mval = 0;
             mval = 0;
+        }
         if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
                                         (unsigned char *)v->value, -1, -1,
                                         mval))
         if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
                                         (unsigned char *)v->value, -1, -1,
                                         mval))
index c3af2d3d78f87bd58e90ded7e0df44d822e22704..f87dfd07267d497e0feadc5940870bef07a6add1 100644 (file)
@@ -146,14 +146,14 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
 /* Macro to test if a field should be copied from src to dest */
 
 #define test_x509_verify_param_copy(field, def) \
 /* Macro to test if a field should be copied from src to dest */
 
 #define test_x509_verify_param_copy(field, def) \
-        (to_overwrite || \
-                ((src->field != def) && (to_default || (dest->field == def))))
+    (to_overwrite \
+         || ((src->field != def) && (to_default || (dest->field == def))))
 
 /* Macro to test and copy a field if necessary */
 
 #define x509_verify_param_copy(field, def) \
 
 /* Macro to test and copy a field if necessary */
 
 #define x509_verify_param_copy(field, def) \
-        if (test_x509_verify_param_copy(field, def)) \
-                dest->field = src->field
+    if (test_x509_verify_param_copy(field, def)) \
+        dest->field = src->field;
 
 int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
                               const X509_VERIFY_PARAM *src)
 
 int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
                               const X509_VERIFY_PARAM *src)
@@ -243,14 +243,16 @@ int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
 static int int_x509_param_set1(char **pdest, size_t *pdestlen,
                                const char *src, size_t srclen)
 {
 static int int_x509_param_set1(char **pdest, size_t *pdestlen,
                                const char *src, size_t srclen)
 {
-    void *tmp;
+    char *tmp;
     if (src) {
         if (srclen == 0)
             srclen = strlen(src);
 
     if (src) {
         if (srclen == 0)
             srclen = strlen(src);
 
-        tmp = OPENSSL_memdup(src, srclen);
+        tmp = OPENSSL_malloc(srclen + 1);
         if (tmp == NULL)
             return 0;
         if (tmp == NULL)
             return 0;
+        memcpy(tmp, src, srclen);
+        tmp[srclen] = '\0'; /* enforce NUL termination */
     } else {
         tmp = NULL;
         srclen = 0;
     } else {
         tmp = NULL;
         srclen = 0;
@@ -379,6 +381,11 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
     return 1;
 }
 
     return 1;
 }
 
+char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx)
+{
+    return sk_OPENSSL_STRING_value(param->hosts, idx);
+}
+
 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                 const char *name, size_t namelen)
 {
 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                 const char *name, size_t namelen)
 {
@@ -425,6 +432,11 @@ void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
         from->peername = NULL;
 }
 
         from->peername = NULL;
 }
 
+char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param)
+{
+    return param->email;
+}
+
 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                  const char *email, size_t emaillen)
 {
 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                  const char *email, size_t emaillen)
 {
@@ -432,6 +444,24 @@ int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                email, emaillen);
 }
 
                                email, emaillen);
 }
 
+static unsigned char
+*int_X509_VERIFY_PARAM_get0_ip(X509_VERIFY_PARAM *param, size_t *plen)
+{
+    if (param == NULL || param->ip == NULL)
+        return NULL;
+    if (plen != NULL)
+        *plen = param->iplen;
+    return param->ip;
+}
+
+char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param)
+{
+    size_t iplen;
+    unsigned char *ip = int_X509_VERIFY_PARAM_get0_ip(param, &iplen);
+
+    return  ip == NULL ? NULL : ipaddr_to_asc(ip, iplen);
+}
+
 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                               const unsigned char *ip, size_t iplen)
 {
 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                               const unsigned char *ip, size_t iplen)
 {
index 27e0a73969b0e04b419e722a9d0648331d40bbc8..f34020cbaaa7def665bd32097a6f9ffe9191b686 100644 (file)
@@ -10,11 +10,13 @@ X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_auth_level,
 X509_VERIFY_PARAM_get_auth_level, X509_VERIFY_PARAM_set_time,
 X509_VERIFY_PARAM_get_time,
 X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies,
 X509_VERIFY_PARAM_get_auth_level, X509_VERIFY_PARAM_set_time,
 X509_VERIFY_PARAM_get_time,
 X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies,
+X509_VERIFY_PARAM_get0_host,
 X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host,
 X509_VERIFY_PARAM_set_hostflags,
 X509_VERIFY_PARAM_get_hostflags,
 X509_VERIFY_PARAM_get0_peername,
 X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host,
 X509_VERIFY_PARAM_set_hostflags,
 X509_VERIFY_PARAM_get_hostflags,
 X509_VERIFY_PARAM_get0_peername,
-X509_VERIFY_PARAM_set1_email, X509_VERIFY_PARAM_set1_ip,
+X509_VERIFY_PARAM_get0_email, X509_VERIFY_PARAM_set1_email,
+X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_get1_ip_asc,
 X509_VERIFY_PARAM_set1_ip_asc
 - X509 verification parameters
 
 X509_VERIFY_PARAM_set1_ip_asc
 - X509 verification parameters
 
@@ -50,6 +52,7 @@ X509_VERIFY_PARAM_set1_ip_asc
                                        int auth_level);
  int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param);
 
                                        int auth_level);
  int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param);
 
+ char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int n);
  int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                  const char *name, size_t namelen);
  int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
  int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                  const char *name, size_t namelen);
  int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
@@ -58,8 +61,10 @@ X509_VERIFY_PARAM_set1_ip_asc
                                       unsigned int flags);
  unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param);
  char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param);
                                       unsigned int flags);
  unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param);
  char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param);
+ char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param);
  int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                   const char *email, size_t emaillen);
  int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                   const char *email, size_t emaillen);
+ char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param);
  int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                                const unsigned char *ip, size_t iplen);
  int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);
  int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                                const unsigned char *ip, size_t iplen);
  int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);
@@ -128,6 +133,11 @@ Security level 1 requires at least 80-bit-equivalent security and is broadly
 interoperable, though it will, for example, reject MD5 signatures or RSA keys
 shorter than 1024 bits.
 
 interoperable, though it will, for example, reject MD5 signatures or RSA keys
 shorter than 1024 bits.
 
+X509_VERIFY_PARAM_get0_host() returns the B<n>th expected DNS hostname that has
+been set using X509_VERIFY_PARAM_set1_host() or X509_VERIFY_PARAM_add1_host().
+To obtain all names start with B<n> = 0 and increment B<n> as long as no NULL
+pointer is returned.
+
 X509_VERIFY_PARAM_set1_host() sets the expected DNS hostname to
 B<name> clearing any previously specified hostname.  If
 B<name> is NULL, or empty the list of hostnames is cleared, and
 X509_VERIFY_PARAM_set1_host() sets the expected DNS hostname to
 B<name> clearing any previously specified hostname.  If
 B<name> is NULL, or empty the list of hostnames is cleared, and
@@ -177,12 +187,17 @@ string is allocated by the library and is no longer valid once the
 associated B<param> argument is freed.  Applications must not free
 the return value.
 
 associated B<param> argument is freed.  Applications must not free
 the return value.
 
+X509_VERIFY_PARAM_get0_email() returns the expected RFC822 email address.
+
 X509_VERIFY_PARAM_set1_email() sets the expected RFC822 email address to
 B<email>.  If B<email> is NUL-terminated, B<emaillen> may be zero, otherwise
 B<emaillen> must be set to the length of B<email>.  When an email address
 is specified, certificate verification automatically invokes
 L<X509_check_email(3)>.
 
 X509_VERIFY_PARAM_set1_email() sets the expected RFC822 email address to
 B<email>.  If B<email> is NUL-terminated, B<emaillen> may be zero, otherwise
 B<emaillen> must be set to the length of B<email>.  When an email address
 is specified, certificate verification automatically invokes
 L<X509_check_email(3)>.
 
+X509_VERIFY_PARAM_get1_ip_asc() returns the expected IP address as a string.
+The caller is responsible for freeing it.
+
 X509_VERIFY_PARAM_set1_ip() sets the expected IP address to B<ip>.
 The B<ip> argument is in binary format, in network byte-order and
 B<iplen> must be set to 4 for IPv4 and 16 for IPv6.  When an IP
 X509_VERIFY_PARAM_set1_ip() sets the expected IP address to B<ip>.
 The B<ip> argument is in binary format, in network byte-order and
 B<iplen> must be set to 4 for IPv4 and 16 for IPv6.  When an IP
@@ -205,6 +220,10 @@ X509_VERIFY_PARAM_set1_email(), X509_VERIFY_PARAM_set1_ip() and
 X509_VERIFY_PARAM_set1_ip_asc() return 1 for success and 0 for
 failure.
 
 X509_VERIFY_PARAM_set1_ip_asc() return 1 for success and 0 for
 failure.
 
+X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), and
+X509_VERIFY_PARAM_get1_ip_asc(), return the string pointers pecified above
+or NULL if the respective value has not been set or on error.
+
 X509_VERIFY_PARAM_get_flags() returns the current verification flags.
 
 X509_VERIFY_PARAM_get_hostflags() returns any current host flags.
 X509_VERIFY_PARAM_get_flags() returns the current verification flags.
 
 X509_VERIFY_PARAM_get_hostflags() returns any current host flags.
@@ -374,6 +393,9 @@ and has no effect.
 
 The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i.
 
 
 The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i.
 
+The X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(),
+and X509_VERIFY_PARAM_get1_ip_asc() functions were added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved.
 =head1 COPYRIGHT
 
 Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved.
index 615cd21ae85d98ea383e3733955413eeb309f73e..03f147888aa0f4f7b5c18c2936a73b09d25ef4ba 100644 (file)
@@ -238,5 +238,6 @@ static ossl_inline void ossl_sleep(unsigned long millis)
 
 char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep,
                               size_t max_len);
 
 char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep,
                               size_t max_len);
+char *ipaddr_to_asc(unsigned char *p, int len);
 
 #endif
 
 #endif
index 84b076a1cb3fad65e0a00b907bad3ce16baaa394..92aed0838091f1b85ad1bcb7ef139b1b6992e00e 100644 (file)
@@ -585,6 +585,7 @@ int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param,
                                     uint32_t flags);
 uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param);
 
                                     uint32_t flags);
 uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param);
 
+char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx);
 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                 const char *name, size_t namelen);
 int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
 int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
                                 const char *name, size_t namelen);
 int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
@@ -594,8 +595,10 @@ void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
 unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param);
 char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param);
 void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *);
 unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param);
 char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param);
 void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *);
+char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param);
 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                  const char *email, size_t emaillen);
 int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
                                  const char *email, size_t emaillen);
+char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param);
 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                               const unsigned char *ip, size_t iplen);
 int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
 int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
                               const unsigned char *ip, size_t iplen);
 int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
index 82ae2e7e845324c26178d38f4878bf389bca9b43..32942a53defef321d4b725ec76d6320ea653753e 100644 (file)
@@ -5072,6 +5072,9 @@ EVP_PKEY_CTX_set_dh_paramgen_generator  ? 3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dh_nid                 ?      3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dh_rfc5114             ?      3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dhx_rfc5114            ?      3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dh_nid                 ?      3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dh_rfc5114             ?      3_0_0   EXIST::FUNCTION:DH
 EVP_PKEY_CTX_set_dhx_rfc5114            ?      3_0_0   EXIST::FUNCTION:DH
+X509_VERIFY_PARAM_get0_host             ?      3_0_0   EXIST::FUNCTION:
+X509_VERIFY_PARAM_get0_email            ?      3_0_0   EXIST::FUNCTION:
+X509_VERIFY_PARAM_get1_ip_asc           ?      3_0_0   EXIST::FUNCTION:
 X509_verify_ex                          ?      3_0_0   EXIST::FUNCTION:
 X509_REQ_verify_ex                      ?      3_0_0   EXIST::FUNCTION:
 X509_ALGOR_copy                         ?      3_0_0   EXIST::FUNCTION:
 X509_verify_ex                          ?      3_0_0   EXIST::FUNCTION:
 X509_REQ_verify_ex                      ?      3_0_0   EXIST::FUNCTION:
 X509_ALGOR_copy                         ?      3_0_0   EXIST::FUNCTION: