📄 v3_utl.c
字号:
else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10; else goto badhex; *q++ = (ch << 4) | cl; } if(len) *len = q - hexbuf; return hexbuf; err: if(hexbuf) OPENSSL_free(hexbuf); X509V3err(X509V3_F_STRING_TO_HEX,ERR_R_MALLOC_FAILURE); return NULL; badhex: OPENSSL_free(hexbuf); X509V3err(X509V3_F_STRING_TO_HEX,X509V3_R_ILLEGAL_HEX_DIGIT); return NULL;}/* V2I name comparison function: returns zero if 'name' matches * cmp or cmp.* */int name_cmp(const char *name, const char *cmp){ int len, ret; char c; len = strlen(cmp); if((ret = strncmp(name, cmp, len))) return ret; c = name[len]; if(!c || (c=='.')) return 0; return 1;}static int sk_strcmp(const char * const *a, const char * const *b){ return strcmp(*a, *b);}STACK *X509_get1_email(X509 *x){ GENERAL_NAMES *gens; STACK *ret; gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); ret = get_email(X509_get_subject_name(x), gens); sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); return ret;}STACK *X509_REQ_get1_email(X509_REQ *x){ GENERAL_NAMES *gens; STACK_OF(X509_EXTENSION) *exts; STACK *ret; exts = X509_REQ_get_extensions(x); gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); ret = get_email(X509_REQ_get_subject_name(x), gens); sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); return ret;}static STACK *get_email(X509_NAME *name, GENERAL_NAMES *gens){ STACK *ret = NULL; X509_NAME_ENTRY *ne; ASN1_IA5STRING *email; GENERAL_NAME *gen; int i; /* Now add any email address(es) to STACK */ i = -1; /* First supplied X509_NAME */ while((i = X509_NAME_get_index_by_NID(name, NID_pkcs9_emailAddress, i)) >= 0) { ne = X509_NAME_get_entry(name, i); email = X509_NAME_ENTRY_get_data(ne); if(!append_ia5(&ret, email)) return NULL; } for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); if(gen->type != GEN_EMAIL) continue; if(!append_ia5(&ret, gen->d.ia5)) return NULL; } return ret;}static void str_free(void *str){ OPENSSL_free(str);}static int append_ia5(STACK **sk, ASN1_IA5STRING *email){ char *emtmp; /* First some sanity checks */ if(email->type != V_ASN1_IA5STRING) return 1; if(!email->data || !email->length) return 1; if(!*sk) *sk = sk_new(sk_strcmp); if(!*sk) return 0; /* Don't add duplicates */ if(sk_find(*sk, (char *)email->data) != -1) return 1; emtmp = BUF_strdup((char *)email->data); if(!emtmp || !sk_push(*sk, emtmp)) { X509_email_free(*sk); *sk = NULL; return 0; } return 1;}void X509_email_free(STACK *sk){ sk_pop_free(sk, str_free);}/* Convert IP addresses both IPv4 and IPv6 into an * OCTET STRING compatible with RFC3280. */ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) { unsigned char ipout[16]; ASN1_OCTET_STRING *ret; int iplen; /* If string contains a ':' assume IPv6 */ iplen = a2i_ipadd(ipout, ipasc); if (!iplen) return NULL; ret = ASN1_OCTET_STRING_new(); if (!ret) return NULL; if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { ASN1_OCTET_STRING_free(ret); return NULL; } return ret; }ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) { ASN1_OCTET_STRING *ret = NULL; unsigned char ipout[32]; char *iptmp = NULL, *p; int iplen1, iplen2; p = strchr(ipasc,'/'); if (!p) return NULL; iptmp = BUF_strdup(ipasc); if (!iptmp) return NULL; p = iptmp + (p - ipasc); *p++ = 0; iplen1 = a2i_ipadd(ipout, iptmp); if (!iplen1) goto err; iplen2 = a2i_ipadd(ipout + iplen1, p); OPENSSL_free(iptmp); iptmp = NULL; if (!iplen2 || (iplen1 != iplen2)) goto err; ret = ASN1_OCTET_STRING_new(); if (!ret) goto err; if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) goto err; return ret; err: if (iptmp) OPENSSL_free(iptmp); if (ret) ASN1_OCTET_STRING_free(ret); return NULL; } int a2i_ipadd(unsigned char *ipout, const char *ipasc) { /* If string contains a ':' assume IPv6 */ if (strchr(ipasc, ':')) { if (!ipv6_from_asc(ipout, ipasc)) return 0; return 16; } else { if (!ipv4_from_asc(ipout, ipasc)) return 0; return 4; } }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) || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) return 0; v4[0] = a0; v4[1] = a1; v4[2] = a2; v4[3] = a3; return 1; }typedef struct { /* Temporary store for IPV6 output */ unsigned char tmp[16]; /* Total number of bytes in tmp */ int total; /* The position of a zero (corresponding to '::') */ int zero_pos; /* Number of zeroes */ int zero_cnt; } IPV6_STAT;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; /* Treat the IPv6 representation as a list of values * separated by ':'. The presence of a '::' will parse * as one, two or three zero length elements. */ if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) return 0; /* Now for some sanity checks */ if (v6stat.zero_pos == -1) { /* If no '::' must have exactly 16 bytes */ if (v6stat.total != 16) return 0; } else { /* If '::' must have less than 16 bytes */ if (v6stat.total == 16) return 0; /* More than three zeroes is an error */ if (v6stat.zero_cnt > 3) return 0; /* Can only have three zeroes if nothing else present */ else if (v6stat.zero_cnt == 3) { if (v6stat.total > 0) return 0; } /* Can only have two zeroes if at start or end */ else if (v6stat.zero_cnt == 2) { if ((v6stat.zero_pos != 0) && (v6stat.zero_pos != v6stat.total)) return 0; } else /* Can only have one zero if *not* start or end */ { if ((v6stat.zero_pos == 0) || (v6stat.zero_pos == v6stat.total)) return 0; } } /* Format result */ /* Copy initial part */ if (v6stat.zero_pos > 0) memcpy(v6, v6stat.tmp, v6stat.zero_pos); /* Zero middle */ if (v6stat.total != 16) memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); /* Copy final part */ if (v6stat.total != v6stat.zero_pos) memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, v6stat.tmp + v6stat.zero_pos, v6stat.total - v6stat.zero_pos); return 1; }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; if (len == 0) { /* Zero length element, corresponds to '::' */ if (s->zero_pos == -1) s->zero_pos = s->total; /* If we've already got a :: its an error */ else if (s->zero_pos != s->total) return 0; s->zero_cnt++; } else { /* If more than 4 characters could be final a.b.c.d form */ if (len > 4) { /* Need at least 4 bytes left */ if (s->total > 12) return 0; /* Must be end of string */ if (elem[len]) return 0; if (!ipv4_from_asc(s->tmp + s->total, elem)) return 0; s->total += 4; } else { if (!ipv6_hex(s->tmp + s->total, elem, len)) return 0; s->total += 2; } } return 1; }/* Convert a string of up to 4 hex digits into the corresponding * IPv6 form. */static int ipv6_hex(unsigned char *out, const char *in, int inlen) { unsigned char c; unsigned int num = 0; if (inlen > 4) return 0; while(inlen--) { c = *in++; num <<= 4; if ((c >= '0') && (c <= '9')) num |= c - '0'; else if ((c >= 'A') && (c <= 'F')) num |= c - 'A' + 10; else if ((c >= 'a') && (c <= 'f')) num |= c - 'a' + 10; else return 0; } out[0] = num >> 8; out[1] = num & 0xff; return 1; }int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, unsigned long chtype) { CONF_VALUE *v; int i, mval; char *p, *type; if (!nm) return 0; for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { v=sk_CONF_VALUE_value(dn_sk,i); type=v->name; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(p = type; *p ; p++) #ifndef CHARSET_EBCDIC if ((*p == ':') || (*p == ',') || (*p == '.'))#else if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.']))#endif { p++; if(*p) type = p; break; }#ifndef CHARSET_EBCDIC if (*type == '+')#else if (*type == os_toascii['+'])#endif { mval = -1; type++; } else mval = 0; if (!X509_NAME_add_entry_by_txt(nm,type, chtype, (unsigned char *) v->value,-1,-1,mval)) return 0; } return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -