int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) { if (!value || (type == V_ASN1_BOOLEAN)) { void *p = (void *)value; ASN1_TYPE_set(a, type, p); } else if (type == V_ASN1_OBJECT) { ASN1_OBJECT *odup; odup = OBJ_dup(value); if (!odup) return 0; ASN1_TYPE_set(a, type, odup); } else { ASN1_STRING *sdup; sdup = ASN1_STRING_dup(value); if (!sdup) return 0; ASN1_TYPE_set(a, type, sdup); } return 1; }
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, int ptype, void *pval, unsigned char *penc, int penclen) { unsigned char **ppenc = NULL; if (version >= 0) { if (!ASN1_INTEGER_set(priv->version, version)) return 0; } if (penc) { int pmtype; ASN1_OCTET_STRING *oct; oct = ASN1_OCTET_STRING_new(); if (!oct) return 0; oct->data = penc; ppenc = &oct->data; oct->length = penclen; if (priv->broken == PKCS8_NO_OCTET) pmtype = V_ASN1_SEQUENCE; else pmtype = V_ASN1_OCTET_STRING; ASN1_TYPE_set(priv->pkey, pmtype, oct); } if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { /* If call fails do not swallow 'enc' */ if (ppenc) *ppenc = NULL; return 0; } return 1; }
X509_ATTRIBUTE * X509_ATTRIBUTE_create(int nid, int atrtype, void *value) { X509_ATTRIBUTE *ret = NULL; ASN1_TYPE *val = NULL; if ((ret = X509_ATTRIBUTE_new()) == NULL) return (NULL); ret->object = OBJ_nid2obj(nid); ret->single = 0; if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL) goto err; if ((val = ASN1_TYPE_new()) == NULL) goto err; if (!sk_ASN1_TYPE_push(ret->value.set, val)) goto err; ASN1_TYPE_set(val, atrtype, value); return (ret); err: if (ret != NULL) X509_ATTRIBUTE_free(ret); if (val != NULL) ASN1_TYPE_free(val); return (NULL); }
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { int ret; if (c->cipher->set_asn1_parameters != NULL) ret = c->cipher->set_asn1_parameters(c, type); else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) switch (EVP_CIPHER_CTX_mode(c)) { case EVP_CIPH_WRAP_MODE: if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap) ASN1_TYPE_set(type, V_ASN1_NULL, NULL); ret = 1; break; case EVP_CIPH_GCM_MODE: case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: ret = -1; break; default: ret = EVP_CIPHER_set_asn1_iv(c, type); break; } else ret = -1; return ret; }
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) { if (!alg) return 0; if (ptype != V_ASN1_UNDEF) { if (alg->parameter == NULL) alg->parameter = ASN1_TYPE_new(); if (alg->parameter == NULL) return 0; } if (alg) { if (alg->algorithm) ASN1_OBJECT_free(alg->algorithm); alg->algorithm = aobj; } if (ptype == 0) return 1; if (ptype == V_ASN1_UNDEF) { if (alg->parameter) { ASN1_TYPE_free(alg->parameter); alg->parameter = NULL; } } else ASN1_TYPE_set(alg->parameter, ptype, pval); return 1; }
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { int ret; if (c->cipher->set_asn1_parameters != NULL) ret = c->cipher->set_asn1_parameters(c, type); else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { switch (EVP_CIPHER_CTX_mode(c)) { case EVP_CIPH_WRAP_MODE: ASN1_TYPE_set(type, V_ASN1_NULL, NULL); ret = 1; break; case EVP_CIPH_GCM_MODE: case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: ret = -1; break; default: ret = EVP_CIPHER_set_asn1_iv(c, type); } } else ret = -1; return (ret); }
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) { ASN1_STRING *os; if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0); if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0); ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os); return(1); }
int gost2814789_set_asn1_params(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) { int len = 0; unsigned char *buf = NULL; unsigned char *p = NULL; EVP_GOST2814789_CTX *c = ctx->cipher_data; ASN1_OCTET_STRING *os = NULL; GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); if (gcp == NULL) { GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } if (ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len) == 0) { GOST_CIPHER_PARAMS_free(gcp); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_ASN1_LIB); return 0; } ASN1_OBJECT_free(gcp->enc_param_set); gcp->enc_param_set = OBJ_nid2obj(c->param_nid); len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); p = buf = malloc(len); if (buf == NULL) { GOST_CIPHER_PARAMS_free(gcp); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } i2d_GOST_CIPHER_PARAMS(gcp, &p); GOST_CIPHER_PARAMS_free(gcp); os = ASN1_OCTET_STRING_new(); if (os == NULL) { free(buf); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } if (ASN1_OCTET_STRING_set(os, buf, len) == 0) { ASN1_OCTET_STRING_free(os); free(buf); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_ASN1_LIB); return 0; } free(buf); ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); return 1; }
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) { ASN1_STRING *os; if ((os = ASN1_OCTET_STRING_new()) == NULL) return 0; if (!ASN1_OCTET_STRING_set(os, data, len)) { ASN1_OCTET_STRING_free(os); return 0; } ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os); return 1; }
/* Set cipher parameters from ASN1 structure */ int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params) { int len=0; unsigned char *buf=NULL; unsigned char *p=NULL; struct ossl_gost_cipher_ctx *c = ctx->cipher_data; GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); ASN1_OCTET_STRING *os = NULL; if (!gcp) { GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); return 0; } if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) { GOST_CIPHER_PARAMS_free(gcp); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); return 0; } ASN1_OBJECT_free(gcp->enc_param_set); gcp->enc_param_set = OBJ_nid2obj(c->paramNID); len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); p = buf = (unsigned char*)OPENSSL_malloc(len); if (!buf) { GOST_CIPHER_PARAMS_free(gcp); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); return 0; } i2d_GOST_CIPHER_PARAMS(gcp, &p); GOST_CIPHER_PARAMS_free(gcp); os = ASN1_OCTET_STRING_new(); if(!os || !ASN1_OCTET_STRING_set(os, buf, len)) { OPENSSL_free(buf); GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); return 0; } OPENSSL_free(buf); ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); return 1; }
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { int ret; if (c->cipher->set_asn1_parameters != NULL) ret=c->cipher->set_asn1_parameters(c,type); else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { if (EVP_CIPHER_CTX_mode(c) == EVP_CIPH_WRAP_MODE) { ASN1_TYPE_set(type, V_ASN1_NULL, NULL); ret = 1; } else ret=EVP_CIPHER_set_asn1_iv(c, type); } else ret=-1; return(ret); }
int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, int len) { int n, size; ASN1_OCTET_STRING os, *osp; ASN1_INTEGER in; unsigned char *p; unsigned char buf[32]; /* when they have 256bit longs, * I'll be in trouble */ in.data = buf; in.length = 32; os.data = data; os.type = V_ASN1_OCTET_STRING; os.length = len; ASN1_INTEGER_set(&in, num); n = i2d_ASN1_INTEGER(&in, NULL); n += M_i2d_ASN1_OCTET_STRING(&os, NULL); size = ASN1_object_size(1, n, V_ASN1_SEQUENCE); if ((osp = ASN1_STRING_new()) == NULL) return (0); /* Grow the 'string' */ if (!ASN1_STRING_set(osp, NULL, size)) { ASN1_STRING_free(osp); return (0); } M_ASN1_STRING_length_set(osp, size); p = M_ASN1_STRING_data(osp); ASN1_put_object(&p, 1,n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); i2d_ASN1_INTEGER(&in, &p); M_i2d_ASN1_OCTET_STRING(&os, &p); ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp); return (1); }
ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t) { ASN1_OCTET_STRING *oct; ASN1_TYPE *rt; oct = ASN1_item_pack(s, it, NULL); if (oct == NULL) return NULL; if (t && *t) { rt = *t; } else { rt = ASN1_TYPE_new(); if (rt == NULL) { ASN1_OCTET_STRING_free(oct); return NULL; } if (t) *t = rt; } ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct); return rt; }
/* * We need to replace a standard chunk of PKCS7 signature with one mandated * by Authenticode. Problem is, replacing it just like that and then calling * PKCS7_final() would make OpenSSL segfault somewhere in PKCS7_dataFinal(). * So, instead, we call PKCS7_dataInit(), then put our Authenticode-specific * data into BIO it returned, then call PKCS7_dataFinal() - which now somehow * does not panic - and _then_ we replace it in the signature. This technique * was used in sbsigntool by Jeremy Kerr, and might have originated in * osslsigncode. */ static void magic(PKCS7 *pkcs7, const char *digest, size_t digest_len) { BIO *bio, *t_bio; ASN1_TYPE *t; ASN1_STRING *s; CONF *cnf; unsigned char *buf, *tmp; char *digest_hex, *magic_conf, *str; int len, nid, ok; digest_hex = bin2hex(digest, digest_len); /* * Construct the SpcIndirectDataContent chunk. */ nid = OBJ_create("1.3.6.1.4.1.311.2.1.4", NULL, NULL); asprintf(&magic_conf, magic_fmt, digest_hex); if (magic_conf == NULL) err(1, "asprintf"); bio = BIO_new_mem_buf((void *)magic_conf, -1); if (bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "BIO_new_mem_buf(3) failed"); } cnf = NCONF_new(NULL); if (cnf == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_new(3) failed"); } ok = NCONF_load_bio(cnf, bio, NULL); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "NCONF_load_bio(3) failed"); } str = NCONF_get_string(cnf, "default", "asn1"); if (str == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_get_string(3) failed"); } t = ASN1_generate_nconf(str, cnf); if (t == NULL) { ERR_print_errors_fp(stderr); errx(1, "ASN1_generate_nconf(3) failed"); } /* * We now have our proprietary piece of ASN.1. Let's do * the actual signing. */ len = i2d_ASN1_TYPE(t, NULL); tmp = buf = calloc(1, len); if (tmp == NULL) err(1, "calloc"); i2d_ASN1_TYPE(t, &tmp); /* * We now have contents of 't' stuffed into memory buffer 'buf'. */ tmp = NULL; t = NULL; t_bio = PKCS7_dataInit(pkcs7, NULL); if (t_bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataInit(3) failed"); } BIO_write(t_bio, buf + 2, len - 2); ok = PKCS7_dataFinal(pkcs7, t_bio); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataFinal(3) failed"); } t = ASN1_TYPE_new(); s = ASN1_STRING_new(); ASN1_STRING_set(s, buf, len); ASN1_TYPE_set(t, V_ASN1_SEQUENCE, s); PKCS7_set0_type_other(pkcs7->d.sign->contents, nid, t); }
ASN1_TYPE* ossl_asn1_get_asn1type(VALUE obj) { ASN1_TYPE *ret; VALUE value, rflag; void *ptr; void (*free_func)(); long tag, flag; tag = ossl_asn1_default_tag(obj); value = ossl_asn1_get_value(obj); switch(tag){ case V_ASN1_BOOLEAN: ptr = (void*)(VALUE)obj_to_asn1bool(value); free_func = NULL; break; case V_ASN1_INTEGER: /* FALLTHROUGH */ case V_ASN1_ENUMERATED: ptr = obj_to_asn1int(value); free_func = ASN1_INTEGER_free; break; case V_ASN1_BIT_STRING: rflag = rb_attr_get(obj, rb_intern("@unused_bits")); flag = NIL_P(rflag) ? -1 : NUM2INT(rflag); ptr = obj_to_asn1bstr(value, flag); free_func = ASN1_BIT_STRING_free; break; case V_ASN1_NULL: ptr = obj_to_asn1null(value); free_func = ASN1_NULL_free; break; case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ case V_ASN1_UTF8STRING: /* FALLTHROUGH */ case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ case V_ASN1_T61STRING: /* FALLTHROUGH */ case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ case V_ASN1_IA5STRING: /* FALLTHROUGH */ case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ case V_ASN1_ISO64STRING: /* FALLTHROUGH */ case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ case V_ASN1_BMPSTRING: ptr = obj_to_asn1str(value); free_func = ASN1_STRING_free; break; case V_ASN1_OBJECT: ptr = obj_to_asn1obj(value); free_func = ASN1_OBJECT_free; break; case V_ASN1_UTCTIME: ptr = obj_to_asn1utime(value); free_func = ASN1_TIME_free; break; case V_ASN1_GENERALIZEDTIME: ptr = obj_to_asn1gtime(value); free_func = ASN1_TIME_free; break; case V_ASN1_SET: /* FALLTHROUGH */ case V_ASN1_SEQUENCE: ptr = obj_to_asn1derstr(obj); free_func = ASN1_STRING_free; break; default: ossl_raise(eASN1Error, "unsupported ASN.1 type"); } if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){ if(free_func) free_func(ptr); ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); } memset(ret, 0, sizeof(ASN1_TYPE)); ASN1_TYPE_set(ret, tag, ptr); 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; }
/* * Creates a x509v3 extension containing a hash * * DigestInfo ::= SEQUENCE { * digestAlgorithm AlgorithmIdentifier, * digest OCTET STRING * } * * AlgorithmIdentifier ::= SEQUENCE { * algorithm OBJECT IDENTIFIER, * parameters ANY DEFINED BY algorithm OPTIONAL * } * * Parameters: * nid: extension identifier * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) * md: hash algorithm * buf: pointer to the buffer that contains the hash * len: size of the hash in bytes * * Return: Extension address, NULL if error */ X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md, unsigned char *buf, size_t len) { X509_EXTENSION *ex; ASN1_OCTET_STRING *octet; HASH *hash; ASN1_OBJECT *algorithm; X509_ALGOR *x509_algor; unsigned char *p = NULL; int sz; /* OBJECT_IDENTIFIER with hash algorithm */ algorithm = OBJ_nid2obj(EVP_MD_type(md)); if (algorithm == NULL) { return NULL; } /* Create X509_ALGOR */ x509_algor = X509_ALGOR_new(); if (x509_algor == NULL) { return NULL; } x509_algor->algorithm = algorithm; x509_algor->parameter = ASN1_TYPE_new(); ASN1_TYPE_set(x509_algor->parameter, V_ASN1_NULL, NULL); /* OCTET_STRING with the actual hash */ octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { X509_ALGOR_free(x509_algor); return NULL; } ASN1_OCTET_STRING_set(octet, buf, len); /* HASH structure containing algorithm + hash */ hash = HASH_new(); if (hash == NULL) { ASN1_OCTET_STRING_free(octet); X509_ALGOR_free(x509_algor); return NULL; } hash->hashAlgorithm = x509_algor; hash->dataHash = octet; /* DER encoded HASH */ sz = i2d_HASH(hash, &p); if ((sz <= 0) || (p == NULL)) { HASH_free(hash); X509_ALGOR_free(x509_algor); return NULL; } /* Create the extension */ ex = ext_new(nid, crit, p, sz); /* Clean up */ OPENSSL_free(p); HASH_free(hash); return ex; }