diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c index 4347c76c3da6351c7643cb3121007984f152e571..0e8211b0075abcf013ffd8975fc08b66a401e049 100644 --- a/crypto/x509v3/v3_alt.c +++ b/crypto/x509v3/v3_alt.c @@ -73,7 +73,7 @@ GENERAL_NAMES_free, i2d_GENERAL_NAMES, NULL, NULL, (X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)NULL /*v2i_GENERAL_NAMES*/, +(X509V3_EXT_V2I)v2i_GENERAL_NAMES, NULL, NULL}, { NID_issuer_alt_name, 0, (X509V3_EXT_NEW)GENERAL_NAMES_new, @@ -82,7 +82,7 @@ GENERAL_NAMES_free, i2d_GENERAL_NAMES, NULL, NULL, (X509V3_EXT_I2V)i2v_GENERAL_NAMES, -(X509V3_EXT_V2I)NULL /*v2i_GENERAL_NAMES*/, +(X509V3_EXT_V2I)v2i_GENERAL_NAMES, NULL, NULL}, EXT_END }; @@ -94,49 +94,167 @@ STACK *ret; { int i; GENERAL_NAME *gen; - char oline[256]; for(i = 0; i < sk_num(gens); i++) { gen = (GENERAL_NAME *)sk_value(gens, i); - switch (gen->type) - { - case GEN_OTHERNAME: + ret = i2v_GENERAL_NAME(method, gen, ret); + } + return ret; +} + +STACK *i2v_GENERAL_NAME(method, gen, ret) +X509V3_EXT_METHOD *method; +GENERAL_NAME *gen; +STACK *ret; +{ + char oline[256]; + unsigned char *p; + switch (gen->type) + { + case GEN_OTHERNAME: X509V3_add_value("othername","", &ret); break; - case GEN_X400: + case GEN_X400: X509V3_add_value("X400Name","", &ret); break; - case GEN_EDIPARTY: + case GEN_EDIPARTY: X509V3_add_value("EdiPartyName","", &ret); - break; + break; - case GEN_EMAIL: + case GEN_EMAIL: X509V3_add_value("email",gen->d.ia5->data, &ret); break; - case GEN_DNS: + case GEN_DNS: X509V3_add_value("DNS",gen->d.ia5->data, &ret); break; - case GEN_URI: + case GEN_URI: X509V3_add_value("URI",gen->d.ia5->data, &ret); - break; + break; - case GEN_DIRNAME: + case GEN_DIRNAME: X509_NAME_oneline(gen->d.dirn, oline, 256); X509V3_add_value("DirName",oline, &ret); - break; - - case GEN_IPADD: - X509V3_add_value("IP Address","", &ret); - break; + break; - case GEN_RID: - X509V3_add_value("Registered ID","", &ret); - break; + case GEN_IPADD: + p = gen->d.ip->data; + /* BUG: doesn't support IPV6 */ + if(gen->d.ip->length != 4) { + X509V3_add_value("IP Address","", &ret); + break; } + sprintf(oline, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + X509V3_add_value("IP Address",oline, &ret); + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + X509V3_add_value("Registered ID",oline, &ret); + break; } return ret; } +STACK *v2i_GENERAL_NAMES(method, ctx, nval) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK *nval; +{ + GENERAL_NAME *gen; + STACK *gens = NULL; + CONF_VALUE *cnf; + int i; + if(!(gens = sk_new(NULL))) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES,ERR_R_MALLOC_FAILURE); + return NULL; + } + for(i = 0; i < sk_num(nval); i++) { + cnf = (CONF_VALUE *)sk_value(nval, i); + if(!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) goto err; + sk_push(gens, (char *)gen); + } + return gens; + err: + sk_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME(method, ctx, cnf) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +CONF_VALUE *cnf; +{ +char is_string = 0; +int type; +GENERAL_NAME *gen = NULL; + +char *name, *value; + +name = cnf->name; +value = cnf->value; + +if(!(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); + return NULL; +} + +if(!name_cmp(name, "email")) { + is_string = 1; + type = GEN_EMAIL; +} else if(!name_cmp(name, "URI")) { + is_string = 1; + type = GEN_URI; +} else if(!name_cmp(name, "DNS")) { + is_string = 1; + type = GEN_DNS; +} else if(!name_cmp(name, "RID")) { + ASN1_OBJECT *obj; + if(!(obj = OBJ_txt2obj(value,0))) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; + } + gen->d.rid = obj; + type = GEN_RID; +} else if(!name_cmp(name, "IP")) { + int i1,i2,i3,i4; + unsigned char ip[4]; + if((sscanf(value, "%d.%d.%d.%d",&i1,&i2,&i3,&i4) != 4) || + (i1 < 0) || (i1 > 255) || (i2 < 0) || (i2 > 255) || + (i3 < 0) || (i3 > 255) || (i4 < 0) || (i4 > 255) ) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + ip[0] = i1; ip[1] = i2 ; ip[2] = i3 ; ip[3] = i4; + if(!(gen->d.ip = ASN1_OCTET_STRING_new()) || + !ASN1_STRING_set(gen->d.ip, ip, 4)) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); + goto err; + } + type = GEN_IPADD; +} else { + X509V3err(X509V3_F_V2I_GENERAL_NAME,X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + goto err; +} + +if(is_string) { + if(!(gen->d.ia5 = ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, value, strlen(value))) { + X509V3err(X509V3_F_V2I_GENERAL_NAME,ERR_R_MALLOC_FAILURE); + goto err; + } +} + +gen->type = type; + +return gen; + +err: +GENERAL_NAME_free(gen); +return NULL; +} diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c index 2c3a8912547f044e280fb85048a67f9cf2e5d2cf..45a3a5623453c50c831c7f5500c4b752679d057d 100644 --- a/crypto/x509v3/v3_utl.c +++ b/crypto/x509v3/v3_utl.c @@ -58,6 +58,7 @@ /* X509 v3 extension utilities */ #include +#include #include #include #include @@ -393,3 +394,20 @@ long *len; return NULL; } + +/* V2I name comparison function: returns zero if 'name' matches + * cmp or cmp.* + */ + +int name_cmp(name, cmp) +char *name; +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; +} diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c index 1b25677fa91844a32040757520a5c27bcfb9b5d8..7cbb82181791abcfd0672d07ccc604a3dcb289d0 100644 --- a/crypto/x509v3/v3err.c +++ b/crypto/x509v3/v3err.c @@ -72,6 +72,8 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_PACK(0,X509V3_F_V2I_ASN1_BIT_STRING,0), "V2I_ASN1_BIT_STRING"}, {ERR_PACK(0,X509V3_F_V2I_BASIC_CONSTRAINTS,0), "V2I_BASIC_CONSTRAINTS"}, {ERR_PACK(0,X509V3_F_V2I_EXT_KU,0), "V2I_EXT_KU"}, +{ERR_PACK(0,X509V3_F_V2I_GENERAL_NAME,0), "v2i_GENERAL_NAME"}, +{ERR_PACK(0,X509V3_F_V2I_GENERAL_NAMES,0), "v2i_GENERAL_NAMES"}, {ERR_PACK(0,X509V3_F_V3_GENERIC_EXTENSION,0), "V3_GENERIC_EXTENSION"}, {ERR_PACK(0,X509V3_F_X509V3_ADD_EXT,0), "X509V3_ADD_EXT"}, {ERR_PACK(0,X509V3_F_X509V3_ADD_VALUE,0), "X509V3_add_value"}, @@ -85,6 +87,8 @@ static ERR_STRING_DATA X509V3_str_functs[]= static ERR_STRING_DATA X509V3_str_reasons[]= { +{X509V3_R_BAD_IP_ADDRESS ,"bad ip address"}, +{X509V3_R_BAD_OBJECT ,"bad object"}, {X509V3_R_BN_DEC2BN_ERROR ,"bn dec2bn error"}, {X509V3_R_BN_TO_ASN1_INTEGER_ERROR ,"bn to asn1 integer error"}, {X509V3_R_EXTENSION_NAME_ERROR ,"extension name error"}, @@ -102,6 +106,7 @@ static ERR_STRING_DATA X509V3_str_reasons[]= {X509V3_R_NO_PUBLIC_KEY ,"no public key"}, {X509V3_R_ODD_NUMBER_OF_DIGITS ,"odd number of digits"}, {X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT ,"unknown bit string argument"}, +{X509V3_R_UNSUPPORTED_OPTION ,"unsupported option"}, {0,NULL}, }; diff --git a/crypto/x509v3/x509v3.err b/crypto/x509v3/x509v3.err index 9b7474c4cc2592422ad5978547eddd9cd3f7ad78..1aa2a8a87dcc45e8e82bb0856eadff74c85a9b01 100644 --- a/crypto/x509v3/x509v3.err +++ b/crypto/x509v3/x509v3.err @@ -10,6 +10,8 @@ #define X509V3_F_V2I_ASN1_BIT_STRING 101 #define X509V3_F_V2I_BASIC_CONSTRAINTS 102 #define X509V3_F_V2I_EXT_KU 103 +#define X509V3_F_V2I_GENERAL_NAME 117 +#define X509V3_F_V2I_GENERAL_NAMES 118 #define X509V3_F_V3_GENERIC_EXTENSION 116 #define X509V3_F_X509V3_ADD_EXT 104 #define X509V3_F_X509V3_ADD_VALUE 105 @@ -20,6 +22,8 @@ #define X509V3_F_X509V3_VALUE_GET_BOOL 110 /* Reason codes. */ +#define X509V3_R_BAD_IP_ADDRESS 118 +#define X509V3_R_BAD_OBJECT 119 #define X509V3_R_BN_DEC2BN_ERROR 100 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 #define X509V3_R_EXTENSION_NAME_ERROR 115 @@ -37,3 +41,4 @@ #define X509V3_R_NO_PUBLIC_KEY 114 #define X509V3_R_ODD_NUMBER_OF_DIGITS 112 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +#define X509V3_R_UNSUPPORTED_OPTION 117 diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index e828d4be0e540af6e2272351dbc9f540b042cce4..09cf48980238cc17a078bc74ce5515683082049c 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -204,6 +204,7 @@ int i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **pp); GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **a, unsigned char **pp, long length); GENERAL_NAME *GENERAL_NAME_new(void); void GENERAL_NAME_free(GENERAL_NAME *a); +STACK *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK *ret); int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *a, unsigned char **pp); AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **a, unsigned char **pp, long length); @@ -215,6 +216,7 @@ void GENERAL_NAMES_free(STACK *a); STACK *d2i_GENERAL_NAMES(STACK **a, unsigned char **pp, long length); int i2d_GENERAL_NAMES(STACK *a, unsigned char **pp); STACK *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, STACK *gen, STACK *extlist); +STACK *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK *nval); char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); @@ -225,6 +227,7 @@ void ext_ku_free(STACK *a); STACK *ext_ku_new(void); #ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, CONF_VALUE *cnf); void X509V3_conf_free(CONF_VALUE *val); X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value); X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value); @@ -248,6 +251,7 @@ STACK *X509V3_parse_list(char *line); char *hex_to_string(unsigned char *buffer, long len); unsigned char *string_to_hex(char *str, long *len); +int name_cmp(char *name, char *cmp); int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, int flag); int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag); @@ -264,12 +268,15 @@ int i2d_GENERAL_NAME(); GENERAL_NAME *d2i_GENERAL_NAME(); GENERAL_NAME *GENERAL_NAME_new(); void GENERAL_NAME_free(); +STACK *i2v_GENERAL_NAME(); +GENERAL_NAME *v2i_GENERAL_NAME(); STACK *GENERAL_NAMES_new(): void GENERAL_NAMES_free(): STACK *d2i_GENERAL_NAMES(); int i2d_GENERAL_NAMES(); STACK *i2v_GENERAL_NAMES(); +STACK *v2i_GENERAL_NAMES(); char *i2s_ASN1_OCTET_STRING(); ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(); @@ -303,6 +310,7 @@ STACK *X509V3_parse_list(); char *hex_to_string(); unsigned char *string_to_hex(); +int name_cmp(); int X509V3_EXT_print(); int X509V3_EXT_print_fp(); @@ -321,6 +329,8 @@ int X509V3_EXT_print_fp(); #define X509V3_F_V2I_ASN1_BIT_STRING 101 #define X509V3_F_V2I_BASIC_CONSTRAINTS 102 #define X509V3_F_V2I_EXT_KU 103 +#define X509V3_F_V2I_GENERAL_NAME 117 +#define X509V3_F_V2I_GENERAL_NAMES 118 #define X509V3_F_V3_GENERIC_EXTENSION 116 #define X509V3_F_X509V3_ADD_EXT 104 #define X509V3_F_X509V3_ADD_VALUE 105 @@ -331,6 +341,8 @@ int X509V3_EXT_print_fp(); #define X509V3_F_X509V3_VALUE_GET_BOOL 110 /* Reason codes. */ +#define X509V3_R_BAD_IP_ADDRESS 118 +#define X509V3_R_BAD_OBJECT 119 #define X509V3_R_BN_DEC2BN_ERROR 100 #define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 #define X509V3_R_EXTENSION_NAME_ERROR 115 @@ -348,6 +360,7 @@ int X509V3_EXT_print_fp(); #define X509V3_R_NO_PUBLIC_KEY 114 #define X509V3_R_ODD_NUMBER_OF_DIGITS 112 #define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +#define X509V3_R_UNSUPPORTED_OPTION 117 #ifdef __cplusplus }