static ASN1_TYPE * asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { ASN1_TYPE *ret = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; unsigned char *der = NULL; int derlen; int i; sk = sk_ASN1_TYPE_new_null(); if (!sk) goto bad; if (section) { if (!cnf) goto bad; sect = X509V3_get_section(cnf, (char *)section); if (!sect) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { ASN1_TYPE *typ = ASN1_generate_v3( sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; if (!sk_ASN1_TYPE_push(sk, typ)) goto bad; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) derlen = i2d_ASN1_SET_ANY(sk, &der); else derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); if (derlen < 0) goto bad; if (!(ret = ASN1_TYPE_new())) goto bad; if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) goto bad; ret->type = utype; ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; der = NULL; bad: free(der); if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); if (sect) X509V3_section_free(cnf, sect); return ret; }
static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) { ASN1_TYPE *typ; ASN1_STRING *str; int utype; if (!it) return 0; if (it->funcs) { const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; if (pf->prim_new) return pf->prim_new(pval, it); } if (it->itype == ASN1_ITYPE_MSTRING) utype = -1; else utype = it->utype; switch (utype) { case V_ASN1_OBJECT: *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); return 1; case V_ASN1_BOOLEAN: *(ASN1_BOOLEAN *)pval = it->size; return 1; case V_ASN1_NULL: *pval = (ASN1_VALUE *)1; return 1; case V_ASN1_ANY: typ = OPENSSL_malloc(sizeof(*typ)); if (typ == NULL) return 0; typ->value.ptr = NULL; typ->type = -1; *pval = (ASN1_VALUE *)typ; break; default: if (embed) { str = *(ASN1_STRING **)pval; memset(str, 0, sizeof(*str)); str->type = utype; str->flags = ASN1_STRING_FLAG_EMBED; } else { str = ASN1_STRING_type_new(utype); *pval = (ASN1_VALUE *)str; } if (it->itype == ASN1_ITYPE_MSTRING && str) str->flags |= ASN1_STRING_FLAG_MSTRING; break; } if (*pval) return 1; return 0; }
int ASN1_primitive_new (ASN1_VALUE ** pval, const ASN1_ITEM * it) { ASN1_TYPE *typ; ASN1_STRING *str; int utype; if (it && it->funcs) { const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; if (pf->prim_new) return pf->prim_new (pval, it); } if (!it || (it->itype == ASN1_ITYPE_MSTRING)) utype = -1; else utype = it->utype; switch (utype) { case V_ASN1_OBJECT: *pval = (ASN1_VALUE *) OBJ_nid2obj (NID_undef); return 1; case V_ASN1_BOOLEAN: *(ASN1_BOOLEAN *) pval = it->size; return 1; case V_ASN1_NULL: *pval = (ASN1_VALUE *) 1; return 1; case V_ASN1_ANY: typ = OPENSSL_malloc (sizeof (ASN1_TYPE)); if (!typ) return 0; typ->value.ptr = NULL; typ->type = -1; *pval = (ASN1_VALUE *) typ; break; default: str = ASN1_STRING_type_new (utype); if (it->itype == ASN1_ITYPE_MSTRING && str) str->flags |= ASN1_STRING_FLAG_MSTRING; *pval = (ASN1_VALUE *) str; break; } if (*pval) return 1; return 0; }
static int openssl_xext_data(lua_State* L) { int ret = 0; X509_EXTENSION *x = CHECK_OBJECT(1, X509_EXTENSION, "openssl.x509_extension"); if (lua_isnone(L, 2)) { ASN1_STRING *s = X509_EXTENSION_get_data(x); s = ASN1_STRING_dup(s); PUSH_OBJECT(s, "openssl.asn1_string"); return 1; } else if (lua_isstring(L, 2)) { size_t size; const char* data = lua_tolstring(L, 2, &size); ASN1_STRING* s = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); if (ASN1_STRING_set(s, data, size) == 1) { ret = X509_EXTENSION_set_data(x, s); } ASN1_STRING_free(s); return openssl_pushresult(L, ret); } else { ASN1_STRING* s = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group"); if (ASN1_STRING_type(s) == V_ASN1_OCTET_STRING) { int ret; ret = X509_EXTENSION_set_data(x, s); return openssl_pushresult(L, ret); } else { luaL_argerror(L, 2, "asn1_string type must be octet"); } } return 0; };
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask, long minsize, long maxsize) { int str_type; int ret; char free_out; int outform, outlen = 0; ASN1_STRING *dest; unsigned char *p; int nchar; char strbuf[32]; int (*cpyfunc) (unsigned long, void *) = NULL; if (len == -1) len = sgx_strlen((const char *)in); if (!mask) mask = DIRSTRING_TYPE; /* First do a string check and work out the number of characters */ switch (inform) { case MBSTRING_BMP: if (len & 1) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_BMPSTRING_LENGTH); return -1; } nchar = len >> 1; break; case MBSTRING_UNIV: if (len & 3) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); return -1; } nchar = len >> 2; break; case MBSTRING_UTF8: nchar = 0; /* This counts the characters and does utf8 syntax checking */ ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); if (ret < 0) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); return -1; } break; case MBSTRING_ASC: nchar = len; break; default: ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); return -1; } if ((minsize > 0) && (nchar < minsize)) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize); ERR_add_error_data(2, "minsize=", strbuf); return -1; } if ((maxsize > 0) && (nchar > maxsize)) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); ERR_add_error_data(2, "maxsize=", strbuf); return -1; } /* Now work out minimal type (if any) */ if (traverse_string(in, len, inform, type_str, &mask) < 0) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); return -1; } /* Now work out output format and string type */ outform = MBSTRING_ASC; if (mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING; else if (mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING; else if (mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING; else if (mask & B_ASN1_BMPSTRING) { str_type = V_ASN1_BMPSTRING; outform = MBSTRING_BMP; } else if (mask & B_ASN1_UNIVERSALSTRING) { str_type = V_ASN1_UNIVERSALSTRING; outform = MBSTRING_UNIV; } else { str_type = V_ASN1_UTF8STRING; outform = MBSTRING_UTF8; } if (!out) return str_type; if (*out) { free_out = 0; dest = *out; if (dest->data) { dest->length = 0; OPENSSL_free(dest->data); dest->data = NULL; } dest->type = str_type; } else { free_out = 1; dest = ASN1_STRING_type_new(str_type); if (!dest) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); return -1; } *out = dest; } /* If both the same type just copy across */ if (inform == outform) { if (!ASN1_STRING_set(dest, in, len)) { ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); return -1; } return str_type; } /* Work out how much space the destination will need */ switch (outform) { case MBSTRING_ASC: outlen = nchar; cpyfunc = cpy_asc; break; case MBSTRING_BMP: outlen = nchar << 1; cpyfunc = cpy_bmp; break; case MBSTRING_UNIV: outlen = nchar << 2; cpyfunc = cpy_univ; break; case MBSTRING_UTF8: outlen = 0; traverse_string(in, len, inform, out_utf8, &outlen); cpyfunc = cpy_utf8; break; } if (!(p = OPENSSL_malloc(outlen + 1))) { if (free_out) ASN1_STRING_free(dest); ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); return -1; } dest->length = outlen; dest->data = p; p[outlen] = 0; traverse_string(in, len, inform, cpyfunc, &p); return str_type; }
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { ASN1_TYPE *ret = NULL, *typ = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; unsigned char *der = NULL, *p; int derlen; int i, is_set; sk = sk_ASN1_TYPE_new_null(); if (section) { if (!cnf) goto bad; sect = X509V3_get_section(cnf, (char *)section); if (!sect) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; sk_ASN1_TYPE_push(sk, typ); typ = NULL; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) is_set = 1; else is_set = 0; derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); der = OPENSSL_malloc(derlen); p = der; i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); if (!(ret = ASN1_TYPE_new())) goto bad; if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) goto bad; ret->type = utype; ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; der = NULL; bad: if (der) OPENSSL_free(der); if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); if (typ) ASN1_TYPE_free(typ); if (sect) X509V3_section_free(cnf, sect); return ret; }
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) { ASN1_VALUE **opval = NULL; ASN1_STRING *stmp; ASN1_TYPE *typ = NULL; int ret = 0; const ASN1_PRIMITIVE_FUNCS *pf; ASN1_INTEGER **tint; pf = it->funcs; if (pf && pf->prim_c2i) return pf->prim_c2i(pval, cont, len, utype, free_cont, it); /* If ANY type clear type and set pointer to internal value */ if (it->utype == V_ASN1_ANY) { if (!*pval) { typ = ASN1_TYPE_new(); if (typ == NULL) goto err; *pval = (ASN1_VALUE *)typ; } else typ = (ASN1_TYPE *)*pval; if (utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); opval = pval; pval = &typ->value.asn1_value; } switch(utype) { case V_ASN1_OBJECT: if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) goto err; break; case V_ASN1_NULL: if (len) { ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); goto err; } *pval = (ASN1_VALUE *)1; break; case V_ASN1_BOOLEAN: if (len != 1) { ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); goto err; } else { ASN1_BOOLEAN *tbool; tbool = (ASN1_BOOLEAN *)pval; *tbool = *cont; } break; case V_ASN1_BIT_STRING: if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) goto err; break; case V_ASN1_INTEGER: case V_ASN1_NEG_INTEGER: case V_ASN1_ENUMERATED: case V_ASN1_NEG_ENUMERATED: tint = (ASN1_INTEGER **)pval; if (!c2i_ASN1_INTEGER(tint, &cont, len)) goto err; /* Fixup type to match the expected form */ (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); break; case V_ASN1_OCTET_STRING: case V_ASN1_NUMERICSTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_VIDEOTEXSTRING: case V_ASN1_IA5STRING: case V_ASN1_UTCTIME: case V_ASN1_GENERALIZEDTIME: case V_ASN1_GRAPHICSTRING: case V_ASN1_VISIBLESTRING: case V_ASN1_GENERALSTRING: case V_ASN1_UNIVERSALSTRING: case V_ASN1_BMPSTRING: case V_ASN1_UTF8STRING: case V_ASN1_OTHER: case V_ASN1_SET: case V_ASN1_SEQUENCE: default: if (utype == V_ASN1_BMPSTRING && (len & 1)) { ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); goto err; } if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); goto err; } /* All based on ASN1_STRING and handled the same */ if (!*pval) { stmp = ASN1_STRING_type_new(utype); if (!stmp) { ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); goto err; } *pval = (ASN1_VALUE *)stmp; } else { stmp = (ASN1_STRING *)*pval; stmp->type = utype; } /* If we've already allocated a buffer use it */ if (*free_cont) { if (stmp->data) OPENSSL_free(stmp->data); stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ stmp->length = len; *free_cont = 0; } else { if (!ASN1_STRING_set(stmp, cont, len)) { ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); ASN1_STRING_free(stmp); *pval = NULL; goto err; } } break; } /* If ASN1_ANY and NULL type fix up value */ if (typ && (utype == V_ASN1_NULL)) typ->value.ptr = NULL; ret = 1; err: if (!ret) { ASN1_TYPE_free(typ); if (opval) *opval = NULL; } return ret; }
static X509_EXTENSION* openssl_new_xextension(lua_State*L, int idx, int v3) { int nid; int critical = 0; ASN1_OCTET_STRING* value = NULL; X509_EXTENSION* y = NULL; lua_getfield(L, idx, "object"); nid = openssl_get_nid(L, -1); lua_pop(L, 1); lua_getfield(L, idx, "critical"); critical = lua_isnil(L, -1) ? 0 : lua_toboolean(L, -1); lua_pop(L, 1); if (nid == NID_undef) { lua_pushfstring(L, "%s is not valid object id", lua_tostring(L, -1)); luaL_argerror(L, idx, lua_tostring(L, -1)); } lua_getfield(L, idx, "value"); luaL_argcheck(L, lua_isstring(L, -1) || auxiliar_isgroup(L, "openssl.asn1group", -1), 1, "field value must be string or openssl.asn1group object"); if (lua_isstring(L, -1)) { size_t size; const char* data = lua_tolstring(L, -1, &size); if (v3) { const X509V3_EXT_METHOD *method = X509V3_EXT_get_nid(nid); if (method) { void *ext_struc = NULL; STACK_OF(CONF_VALUE) *nval = X509V3_parse_list(data); /* Now get internal extension representation based on type */ if (method->v2i && nval) { if (sk_CONF_VALUE_num(nval) > 0) { ext_struc = method->v2i(method, NULL, nval); } } else if (method->s2i) { ext_struc = method->s2i(method, NULL, data); } if (nval) sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); if (ext_struc) { unsigned char *ext_der = NULL; int ext_len; /* Convert internal representation to DER */ if (method->it) { ext_der = NULL; ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); if (ext_len < 0) { ext_der = NULL; } } else { ext_len = method->i2d(ext_struc, NULL); ext_der = OPENSSL_malloc(ext_len); if (ext_der) { unsigned char* p = ext_der; method->i2d(ext_struc, &p); } } if (ext_der) { value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); ASN1_STRING_set(value, ext_der, ext_len); } else value = NULL; if (method->it) ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); else method->ext_free(ext_struc); } } } else { value = ASN1_STRING_type_new(V_ASN1_OCTET_STRING); ASN1_STRING_set(value, data, size); } if (value) { y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); ASN1_STRING_free(value); return y; } else { luaL_error(L, "don't support object(%s) with value (%s)", OBJ_nid2ln(nid), data); return NULL; } } else { value = CHECK_GROUP(-1, ASN1_STRING, "openssl.asn1group"); y = X509_EXTENSION_create_by_NID(NULL, nid, critical, value); lua_pop(L, 1); return y; } }