static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; void *pval = NULL; int ptype; unsigned char *penc = NULL; int penclen; dsa=pkey->pkey.dsa; if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { ASN1_STRING *str; str = ASN1_STRING_new(); str->length = i2d_DSAparams(dsa, &str->data); if (str->length <= 0) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } pval = str; ptype = V_ASN1_SEQUENCE; } else ptype = V_ASN1_UNDEF; dsa->write_params=0; penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, penc, penclen)) return 1; err: if (penc) OPENSSL_free(penc); if (pval) ASN1_STRING_free(pval); return 0; }
static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { ASN1_STRING *params = NULL; ASN1_INTEGER *prkey = NULL; unsigned char *dp = NULL; int dplen; params = ASN1_STRING_new(); if (!params) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data); if (params->length <= 0) { DHerror(ERR_R_MALLOC_FAILURE); goto err; } params->type = V_ASN1_SEQUENCE; /* Get private key into integer */ prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); if (!prkey) { DHerror(DH_R_BN_ERROR); goto err; } dplen = i2d_ASN1_INTEGER(prkey, &dp); ASN1_INTEGER_free(prkey); prkey = NULL; if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0, V_ASN1_SEQUENCE, params, dp, dplen)) goto err; return 1; err: free(dp); ASN1_STRING_free(params); ASN1_INTEGER_free(prkey); return 0; }
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, const unsigned char *salt, int saltlen) { PBEPARAM *pbe = NULL; ASN1_STRING *pbe_str = NULL; unsigned char *sstr; pbe = PBEPARAM_new(); if (pbe == NULL) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(pbe->iter, iter)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } if (!saltlen) saltlen = PKCS5_SALT_LEN; if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } sstr = ASN1_STRING_data(pbe->salt); if (salt) memcpy(sstr, salt, saltlen); else if (RAND_bytes(sstr, saltlen) <= 0) goto err; if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); goto err; } PBEPARAM_free(pbe); pbe = NULL; if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) return 1; err: PBEPARAM_free(pbe); ASN1_STRING_free(pbe_str); return 0; }
static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DH *dh; int ptype; unsigned char *penc = NULL; int penclen; ASN1_STRING *str; ASN1_INTEGER *pub_key = NULL; dh = pkey->pkey.dh; str = ASN1_STRING_new(); if (str == NULL) { DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } str->length = i2d_dhp(pkey, dh, &str->data); if (str->length <= 0) { DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); if (!pub_key) goto err; penclen = i2d_ASN1_INTEGER(pub_key, &penc); ASN1_INTEGER_free(pub_key); if (penclen <= 0) { DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), ptype, str, penc, penclen)) return 1; err: OPENSSL_free(penc); ASN1_STRING_free(str); return 0; }
/* ------------------ private key functions -----------------------------*/ static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) { const unsigned char *pkey_buf = NULL, *p = NULL; int priv_len = 0; BIGNUM *pk_num = NULL; int ret = 0; X509_ALGOR *palg = NULL; ASN1_OBJECT *palg_obj = NULL; ASN1_INTEGER *priv_key = NULL; if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) return 0; p = pkey_buf; if (!decode_gost_algor_params(pk, palg)) { return 0; } if (V_ASN1_OCTET_STRING == *p) { /* New format - Little endian octet string */ unsigned char rev_buf[32]; int i; ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); if (!s || s->length != 32) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } for (i = 0; i < 32; i++) { rev_buf[31 - i] = s->data[i]; } ASN1_STRING_free(s); pk_num = getbnfrombuf(rev_buf, 32); } else { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); if (!priv_key) return 0; ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); ASN1_INTEGER_free(priv_key); if (!ret) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } } ret = gost_set_priv_key(pk, pk_num); BN_free(pk_num); return ret; }
static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; ASN1_STRING *os = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) goto err; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) goto err; if (saltlen == -1) saltlen = EVP_MD_size(sigmd); else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) saltlen--; } pss = RSA_PSS_PARAMS_new(); if (pss == NULL) goto err; if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (pss->saltLength == NULL) goto err; if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) goto err; if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) goto err; /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) goto err; rv = 1; err: RSA_PSS_PARAMS_free(pss); if (rv) return os; ASN1_STRING_free(os); return NULL; }
int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) { switch(type) { case CMS_SIGNERINFO_ISSUER_SERIAL: sid->d.issuerAndSerialNumber = M_ASN1_new_of(CMS_IssuerAndSerialNumber); if (!sid->d.issuerAndSerialNumber) goto merr; if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, X509_get_issuer_name(cert))) goto merr; ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber); sid->d.issuerAndSerialNumber->serialNumber = ASN1_STRING_dup(X509_get_serialNumber(cert)); if(!sid->d.issuerAndSerialNumber->serialNumber) goto merr; break; case CMS_SIGNERINFO_KEYIDENTIFIER: if (!cert->skid) { CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_CERTIFICATE_HAS_NO_KEYID); return 0; } sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); if (!sid->d.subjectKeyIdentifier) goto merr; break; default: CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); return 0; } sid->type = type; return 1; merr: CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); return 0; }
static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { DSA *dsa; ASN1_STRING *pval = NULL; uint8_t *penc = NULL; int penclen; dsa = pkey->pkey.dsa; dsa->write_params = 0; int ptype; if (dsa->p && dsa->q && dsa->g) { pval = ASN1_STRING_new(); if (!pval) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } pval->length = i2d_DSAparams(dsa, &pval->data); if (pval->length <= 0) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } ptype = V_ASN1_SEQUENCE; } else { ptype = V_ASN1_UNDEF; } penclen = i2d_DSAPublicKey(dsa, &penc); if (penclen <= 0) { OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, penc, penclen)) { return 1; } err: OPENSSL_free(penc); ASN1_STRING_free(pval); return 0; }
static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { EC_KEY *ec_key = pkey->pkey.ec; void *pval = NULL; int ptype; uint8_t *penc = NULL, *p; int penclen; if (!eckey_param2type(&ptype, &pval, ec_key)) { OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB); return 0; } penclen = i2o_ECPublicKey(ec_key, NULL); if (penclen <= 0) { goto err; } penc = OPENSSL_malloc(penclen); if (!penc) { goto err; } p = penc; penclen = i2o_ECPublicKey(ec_key, &p); if (penclen <= 0) { goto err; } if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), ptype, pval, penc, penclen)) { return 1; } err: if (ptype == V_ASN1_OBJECT) { ASN1_OBJECT_free(pval); } else { ASN1_STRING_free(pval); } if (penc) { OPENSSL_free(penc); } 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_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); }
static int _checkExpiration(T C, X509_STORE_CTX *ctx, X509 *certificate) { if (C->minimumValidDays) { // If we have warn-X-days-before-expire condition, check the certificate validity (already expired certificates are catched in preverify => we don't need to handle them here). int deltadays = 0; #ifdef HAVE_ASN1_TIME_DIFF int deltaseconds; if (! ASN1_TIME_diff(&deltadays, &deltaseconds, NULL, X509_get_notAfter(certificate))) { X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); snprintf(C->error, sizeof(C->error), "invalid time format (in certificate's notAfter field)"); return 0; } #else ASN1_GENERALIZEDTIME *t = ASN1_TIME_to_generalizedtime(X509_get_notAfter(certificate), NULL); if (! t) { X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); snprintf(C->error, sizeof(C->error), "invalid time format (in certificate's notAfter field)"); return 0; } TRY { deltadays = (double)(Time_toTimestamp((const char *)t->data) - Time_now()) / 86400.; } ELSE { X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD); snprintf(C->error, sizeof(C->error), "invalid time format (in certificate's notAfter field) -- %s", t->data); } FINALLY { ASN1_STRING_free(t); } END_TRY; #endif if (deltadays < C->minimumValidDays) { X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION); snprintf(C->error, sizeof(C->error), "certificate expire in %d days matches check limit [valid > %d days]", deltadays, C->minimumValidDays); return 0; } }
static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); ASN1_STRING *params = encode_gost01_algor_params(pk); unsigned char *priv_buf = NULL; int priv_len; ASN1_INTEGER *asn1key = NULL; if (params == NULL) return 0; asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), NULL); if (asn1key == NULL) { ASN1_STRING_free(params); return 0; } priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); ASN1_INTEGER_free(asn1key); return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, priv_len); }
/* Allocate and set MGF1 algorithm ID from EVP_MD */ static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { X509_ALGOR *algtmp = NULL; ASN1_STRING *stmp = NULL; *palg = NULL; if (EVP_MD_type(mgf1md) == NID_sha1) return 1; /* need to embed algorithm ID inside another */ if (!rsa_md_to_algor(&algtmp, mgf1md)) goto err; if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) goto err; *palg = X509_ALGOR_new(); if (*palg == NULL) goto err; X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); stmp = NULL; err: ASN1_STRING_free(stmp); X509_ALGOR_free(algtmp); if (*palg) return 1; return 0; }
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; }
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 int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) { ASN1_STRING *params = NULL; ASN1_INTEGER *prkey = NULL; ASN1_TYPE *ttmp = NULL; STACK_OF(ASN1_TYPE) *ndsa = NULL; unsigned char *p = NULL, *q; int len; p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa); len = i2d_DSAparams (pkey->pkey.dsa, NULL); if (!(p = OPENSSL_malloc(len))) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } q = p; i2d_DSAparams (pkey->pkey.dsa, &q); if (!(params = ASN1_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_STRING_set(params, p, len)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_free(p); p = NULL; /* Get private key into integer */ if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) { EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); goto err; } switch(p8->broken) { case PKCS8_OK: case PKCS8_NO_OCTET: if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER, &p8->pkey->value.octet_string)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } M_ASN1_INTEGER_free (prkey); prkey = NULL; p8->pkeyalg->parameter->value.sequence = params; params = NULL; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; break; case PKCS8_NS_DB: p8->pkeyalg->parameter->value.sequence = params; params = NULL; p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; if (!(ndsa = sk_ASN1_TYPE_new_null())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp->value.integer = BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) { EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR); goto err; } ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.integer = prkey; prkey = NULL; ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp = NULL; if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; case PKCS8_EMBEDDED_PARAM: p8->pkeyalg->parameter->type = V_ASN1_NULL; if (!(ndsa = sk_ASN1_TYPE_new_null())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.sequence = params; params = NULL; ttmp->type = V_ASN1_SEQUENCE; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!(ttmp = ASN1_TYPE_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp->value.integer = prkey; prkey = NULL; ttmp->type = V_ASN1_INTEGER; if (!sk_ASN1_TYPE_push(ndsa, ttmp)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } ttmp = NULL; if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE, &p8->pkey->value.octet_string->data, &p8->pkey->value.octet_string->length)) { EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE); goto err; } sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); break; } return 1; err: if (p != NULL) OPENSSL_free(p); if (params != NULL) ASN1_STRING_free(params); if (prkey != NULL) M_ASN1_INTEGER_free(prkey); if (ttmp != NULL) ASN1_TYPE_free(ttmp); if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); return 0; }
static int tls_parse_asn1string(struct tls *ctx, ASN1_STRING *a1str, const char **dst_p, int minchars, int maxchars, const char *desc) { int format, len, ret = -1; unsigned char *data; ASN1_STRING *a1utf = NULL; int ascii_only = 0; char *cstr = NULL; int mbres, mbconvert = -1; *dst_p = NULL; format = ASN1_STRING_type(a1str); data = ASN1_STRING_data(a1str); len = ASN1_STRING_length(a1str); if (len < minchars) { tls_set_errorx(ctx, "invalid %s: string too short", desc); goto failed; } switch (format) { case V_ASN1_NUMERICSTRING: case V_ASN1_VISIBLESTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_IA5STRING: /* Ascii */ if (len > maxchars) { tls_set_errorx(ctx, "invalid %s: string too long", desc); goto failed; } ascii_only = 1; break; case V_ASN1_T61STRING: /* Latin1 */ mbconvert = MBSTRING_ASC; break; case V_ASN1_BMPSTRING: /* UCS-2 big-endian */ mbconvert = MBSTRING_BMP; break; case V_ASN1_UNIVERSALSTRING: /* UCS-4 big-endian */ mbconvert = MBSTRING_UNIV; break; case V_ASN1_UTF8STRING: /* * UTF-8 - could be used directly if OpenSSL has already * validated the data. ATM be safe and validate here. */ mbconvert = MBSTRING_UTF8; break; default: tls_set_errorx(ctx, "invalid %s: unexpected string type", desc); goto failed; } /* Convert to UTF-8 */ if (mbconvert != -1) { mbres = ASN1_mbstring_ncopy(&a1utf, data, len, mbconvert, B_ASN1_UTF8STRING, minchars, maxchars); if (mbres < 0) { tls_set_error_libssl(ctx, "invalid %s", desc); goto failed; } if (mbres != V_ASN1_UTF8STRING) { tls_set_errorx(ctx, "multibyte conversion failed: expected UTF8 result"); goto failed; } data = ASN1_STRING_data(a1utf); len = ASN1_STRING_length(a1utf); } /* must not allow \0 */ if (memchr(data, 0, len) != NULL) { tls_set_errorx(ctx, "invalid %s: contains NUL", desc); goto failed; } /* no escape codes please */ if (check_invalid_bytes(ctx, data, len, ascii_only, desc) < 0) goto failed; /* copy to new string */ cstr = malloc(len + 1); if (!cstr) { tls_set_error(ctx, "malloc"); goto failed; } memcpy(cstr, data, len); cstr[len] = 0; *dst_p = cstr; ret = len; failed: ASN1_STRING_free(a1utf); return ret; }
/* type is a 'bitmap' of acceptable string types. */ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, long length, int type) { ASN1_STRING *ret=NULL; const unsigned char *p; unsigned char *s; long len; int inf,tag,xclass; int i=0; p= *pp; inf=ASN1_get_object(&p,&len,&tag,&xclass,length); if (inf & 0x80) goto err; if (tag >= 32) { i=ASN1_R_TAG_VALUE_TOO_HIGH; goto err; } if (!(ASN1_tag2bit(tag) & type)) { i=ASN1_R_WRONG_TYPE; goto err; } /* If a bit-string, exit early */ if (tag == V_ASN1_BIT_STRING) return(d2i_ASN1_BIT_STRING(a,pp,length)); if ((a == NULL) || ((*a) == NULL)) { if ((ret=ASN1_STRING_new()) == NULL) return(NULL); } else ret=(*a); if (len != 0) { s=(unsigned char *)OPENSSL_malloc((int)len+1); if (s == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } memcpy(s,p,(int)len); s[len]='\0'; p+=len; } else s=NULL; if (ret->data != NULL) OPENSSL_free(ret->data); ret->length=(int)len; ret->data=s; ret->type=tag; if (a != NULL) (*a)=ret; *pp=p; return(ret); err: OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_STRING_free(ret); return(NULL); }
static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; ASN1_STRING *params = NULL; void *pval = NULL; unsigned char *buf = NULL, *sptr; int key_size, ret = 0; const EC_POINT *pub_key; BIGNUM *X = NULL, *Y = NULL; const GOST_KEY *ec = pk->pkey.gost; int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); if (pk->save_parameters) { params = encode_gost01_algor_params(pk); if (params == NULL) return 0; pval = params; ptype = V_ASN1_SEQUENCE; } key_size = GOST_KEY_get_size(ec); pub_key = GOST_KEY_get0_public_key(ec); if (pub_key == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); goto err; } octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } ret = ASN1_STRING_set(octet, NULL, 2 * key_size); if (ret == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); goto err; } sptr = ASN1_STRING_data(octet); X = BN_new(); Y = BN_new(); if (X == NULL || Y == NULL) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); goto err; } if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), pub_key, X, Y, NULL) == 0) { GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); goto err; } GOST_bn2le(X, sptr, key_size); GOST_bn2le(Y, sptr + key_size, key_size); BN_free(Y); BN_free(X); ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); if (ret < 0) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); err: BN_free(Y); BN_free(X); ASN1_BIT_STRING_free(octet); ASN1_STRING_free(params); return 0; }
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag) { long l; int ret=0,i; char *m=NULL,mlch = ' '; int nmindent = 0; X509_CINF *ci; ASN1_INTEGER *bs; EVP_PKEY *pkey=NULL; const char *neg; ASN1_STRING *str=NULL; if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } if(nmflags == X509_FLAG_COMPAT) nmindent = 16; ci=x->cert_info; if(!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err; if (BIO_write(bp," Data:\n",10) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_VERSION)) { l=X509_get_version(x); if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_SERIAL)) { if (BIO_write(bp," Serial Number:",22) <= 0) goto err; bs=X509_get_serialNumber(x); if (bs->length <= 4) { l=ASN1_INTEGER_get(bs); if (l < 0) { l= -l; neg="-"; } else neg=""; if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0) goto err; } else { neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":""; if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err; for (i=0; i<bs->length; i++) { if (BIO_printf(bp,"%02x%c",bs->data[i], ((i+1 == bs->length)?'\n':':')) <= 0) goto err; } } } if(!(cflag & X509_FLAG_NO_SIGNAME)) { if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0) goto err; if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; } if(!(cflag & X509_FLAG_NO_ISSUER)) { if (BIO_printf(bp," Issuer:%c",mlch) <= 0) goto err; if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err; if (BIO_write(bp,"\n",1) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_VALIDITY)) { if (BIO_write(bp," Validity\n",17) <= 0) goto err; if (BIO_write(bp," Not Before: ",24) <= 0) goto err; if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err; if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err; if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err; if (BIO_write(bp,"\n",1) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_SUBJECT)) { if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err; if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err; if (BIO_write(bp,"\n",1) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_PUBKEY)) { if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0) goto err; if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0) goto err; if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; pkey=X509_get_pubkey(x); if (pkey == NULL) { BIO_printf(bp,"%12sUnable to load Public Key\n",""); ERR_print_errors(bp); } else #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) { BIO_printf(bp,"%12sRSA Public Key: (%d bit)\n","", BN_num_bits(pkey->pkey.rsa->n)); RSA_print(bp,pkey->pkey.rsa,16); } else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) { BIO_printf(bp,"%12sDSA Public Key:\n",""); DSA_print(bp,pkey->pkey.dsa,16); } else #endif #ifndef OPENSSL_NO_EC if (pkey->type == EVP_PKEY_EC) { BIO_printf(bp, "%12sEC Public Key:\n",""); EC_KEY_print(bp, pkey->pkey.ec, 16); } else #endif BIO_printf(bp,"%12sUnknown Public Key:\n",""); EVP_PKEY_free(pkey); } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) X509V3_extensions_print(bp, "X509v3 extensions", ci->extensions, cflag, 8); if(!(cflag & X509_FLAG_NO_SIGDUMP)) { if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_AUX)) { if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err; } ret=1; err: if (str != NULL) ASN1_STRING_free(str); if (m != NULL) OPENSSL_free(m); return(ret); }
static int priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) { const unsigned char *pkey_buf = NULL, *p = NULL; int priv_len = 0; BIGNUM *pk_num = NULL; int ret = 0; X509_ALGOR *palg = NULL; ASN1_OBJECT *palg_obj = NULL; ASN1_INTEGER *priv_key = NULL; GOST_KEY *ec; int ptype = V_ASN1_UNDEF; ASN1_STRING *pval = NULL; if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0) return 0; (void)EVP_PKEY_assign_GOST(pk, NULL); X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg); if (ptype != V_ASN1_SEQUENCE) { GOSTerr(GOST_F_PUB_DECODE_GOST01, GOST_R_BAD_KEY_PARAMETERS_FORMAT); return 0; } p = pval->data; if (decode_gost01_algor_params(pk, &p, pval->length) == 0) return 0; p = pkey_buf; if (V_ASN1_OCTET_STRING == *p) { /* New format - Little endian octet string */ unsigned char rev_buf[32]; int i; ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); if (s == NULL || s->length != 32) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); ASN1_STRING_free(s); return 0; } for (i = 0; i < 32; i++) { rev_buf[31 - i] = s->data[i]; } ASN1_STRING_free(s); pk_num = BN_bin2bn(rev_buf, 32, NULL); } else { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); if (priv_key == NULL) return 0; ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); ASN1_INTEGER_free(priv_key); if (ret == 0) { GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); return 0; } } ec = pk->pkey.gost; if (ec == NULL) { ec = GOST_KEY_new(); if (ec == NULL) { BN_free(pk_num); return 0; } if (EVP_PKEY_assign_GOST(pk, ec) == 0) { BN_free(pk_num); GOST_KEY_free(ec); return 0; } } if (GOST_KEY_set_private_key(ec, pk_num) == 0) { BN_free(pk_num); return 0; } ret = 0; if (EVP_PKEY_missing_parameters(pk) == 0) ret = gost2001_compute_public(ec) != 0; BN_free(pk_num); return ret; }
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig) { int pad_mode; EVP_PKEY_CTX *pkctx = ctx->pctx; if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; if (pad_mode == RSA_PKCS1_PADDING) return 2; if (pad_mode == RSA_PKCS1_PSS_PADDING) { const EVP_MD *sigmd, *mgf1md; RSA_PSS_PARAMS *pss = NULL; X509_ALGOR *mgf1alg = NULL; ASN1_STRING *os1 = NULL, *os2 = NULL; EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); int saltlen, rv = 0; sigmd = EVP_MD_CTX_md(ctx); if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) goto err; if (saltlen == -1) saltlen = EVP_MD_size(sigmd); else if (saltlen == -2) { saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) saltlen--; } pss = RSA_PSS_PARAMS_new(); if (!pss) goto err; if (saltlen != 20) { pss->saltLength = ASN1_INTEGER_new(); if (!pss->saltLength) goto err; if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) goto err; } if (EVP_MD_type(sigmd) != NID_sha1) { pss->hashAlgorithm = X509_ALGOR_new(); if (!pss->hashAlgorithm) goto err; X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); } if (EVP_MD_type(mgf1md) != NID_sha1) { ASN1_STRING *stmp = NULL; /* need to embed algorithm ID inside another */ mgf1alg = X509_ALGOR_new(); X509_ALGOR_set_md(mgf1alg, mgf1md); if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) goto err; pss->maskGenAlgorithm = X509_ALGOR_new(); if (!pss->maskGenAlgorithm) goto err; X509_ALGOR_set0(pss->maskGenAlgorithm, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); } /* Finally create string with pss parameter encoding. */ if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) goto err; if (alg2) { os2 = ASN1_STRING_dup(os1); if (!os2) goto err; X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os2); } X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os1); os1 = os2 = NULL; rv = 3; err: if (mgf1alg) X509_ALGOR_free(mgf1alg); if (pss) RSA_PSS_PARAMS_free(pss); if (os1) ASN1_STRING_free(os1); return rv; } return 2; }
extern "C" void Asn1StringFree(ASN1_STRING* a) { ASN1_STRING_free(a); }
/* * Get EC key material and stash pointer in ex_data * Note we get called twice, once for private key, and once for public * We need to get the EC_PARAMS and EC_POINT into both, * as lib11 dates from RSA only where all the pub key components * were also part of the private key. With EC the point * is not in the private key, and the params may or may not be. * */ static EVP_PKEY *pkcs11_get_evp_key_ec(PKCS11_KEY * key) { EVP_PKEY *pk; EC_KEY * ec = NULL; CK_RV ckrv; size_t ec_paramslen = 0; CK_BYTE * ec_params = NULL; size_t ec_pointlen = 0; CK_BYTE * ec_point = NULL; PKCS11_KEY * pubkey; ASN1_OCTET_STRING *os=NULL; pk = EVP_PKEY_new(); if (pk == NULL) return NULL; ec = EC_KEY_new(); if (ec == NULL) { EVP_PKEY_free(pk); return NULL; } EVP_PKEY_set1_EC_KEY(pk, ec); /* Also increments the ec ref count */ /* For Openssl req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Even if it fails will continue as a sign only does not need * need this if the pkcs11 or card can figure this out. */ if (key_getattr_var(key, CKA_EC_PARAMS, NULL, &ec_paramslen) == CKR_OK && ec_paramslen > 0) { ec_params = OPENSSL_malloc(ec_paramslen); if (ec_params) { ckrv = key_getattr_var(key, CKA_EC_PARAMS, ec_params, &ec_paramslen); if (ckrv == CKR_OK) { const unsigned char * a = ec_params; /* convert to OpenSSL parmas */ d2i_ECParameters(&ec, &a, (long) ec_paramslen); } } } /* Now get the ec_point */ pubkey = key->isPrivate ? PKCS11_find_key_from_key(key) : key; if (pubkey) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, NULL, &ec_pointlen); if (ckrv == CKR_OK && ec_pointlen > 0) { ec_point = OPENSSL_malloc(ec_pointlen); if (ec_point) { ckrv = key_getattr_var(pubkey, CKA_EC_POINT, ec_point, &ec_pointlen); if (ckrv == CKR_OK) { /* PKCS#11 returns ASN1 octstring*/ const unsigned char * a; /* we have asn1 octet string, need to strip off 04 len */ a = ec_point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long) ec_pointlen); if (os) { a = os->data; o2i_ECPublicKey(&ec, &a, os->length); } /* EC_KEY_print_fp(stderr, ec, 5); */ } } } } /* If the key is not extractable, create a key object * that will use the card's functions to sign & decrypt */ if (os) ASN1_STRING_free(os); if (ec_point) OPENSSL_free(ec_point); if (ec_params) OPENSSL_free(ec_params); if (key->isPrivate) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L EC_KEY_set_method(ec, PKCS11_get_ec_key_method()); #else ECDSA_set_method(ec, PKCS11_get_ecdsa_method()); /* TODO: Retrieve the ECDSA private key object attributes instead, * unless the key has the "sensitive" attribute set */ #endif } /* TODO: Extract the ECDSA private key instead, if the key * is marked as extractable (and not private?) */ #if OPENSSL_VERSION_NUMBER >= 0x10100002L EC_KEY_set_ex_data(ec,ec_key_ex_index, key); #else ECDSA_set_ex_data(ec, ecdsa_ex_index, key); #endif EC_KEY_free(ec); /* drops our reference to it */ return pk; }
static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) { const unsigned char *pkey_buf = NULL, *p = NULL; int priv_len = 0; BIGNUM *pk_num = NULL; int ret = 0; X509_ALGOR *palg = NULL; ASN1_OBJECT *palg_obj = NULL; ASN1_INTEGER *priv_key = NULL; int expected_key_len = 32; if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) return 0; p = pkey_buf; if (!decode_gost_algor_params(pk, palg)) { return 0; } expected_key_len = pkey_bits_gost(pk) > 0 ? pkey_bits_gost(pk) / 8 : 0; if (expected_key_len == 0) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } if (priv_len % expected_key_len == 0) { /* Key is not wrapped but masked */ pk_num = unmask_priv_key(pk, pkey_buf, expected_key_len, priv_len / expected_key_len - 1); } else if (V_ASN1_OCTET_STRING == *p) { /* New format - Little endian octet string */ ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); if (!s || ((s->length != 32) && (s->length != 64))) { ASN1_STRING_free(s); GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } pk_num = hashsum2bn(s->data, s->length); ASN1_STRING_free(s); } else if (V_ASN1_INTEGER == *p) { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); if (!priv_key) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } pk_num = ASN1_INTEGER_to_BN(priv_key, NULL); ASN1_INTEGER_free(priv_key); } else if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == *p) { MASKED_GOST_KEY *mgk = NULL; mgk = d2i_MASKED_GOST_KEY(NULL, &p, priv_len); if (!mgk) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } priv_len = mgk->masked_priv_key->length; if (priv_len % expected_key_len) { MASKED_GOST_KEY_free(mgk); GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } pk_num = unmask_priv_key(pk, mgk->masked_priv_key->data, expected_key_len, priv_len / expected_key_len - 1); MASKED_GOST_KEY_free(mgk); } else { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } if (pk_num == NULL) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } ret = gost_set_priv_key(pk, pk_num); BN_free(pk_num); return ret; }
/* There have been a few bug fixes for this function from * Paul Keogh <*****@*****.**>, many thanks to him */ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) { ASN1_STRING *os=NULL; BUF_MEM b; int num; b.length=0; b.max=0; b.data=NULL; if (a == NULL) { c->error=ERR_R_PASSED_NULL_PARAMETER; goto err; } num=0; for (;;) { if (c->inf & 1) { c->eos=ASN1_const_check_infinite_end(&c->p, (long)(c->max-c->p)); if (c->eos) break; } else { if (c->slen <= 0) break; } c->q=c->p; if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass) == NULL) { c->error=ERR_R_ASN1_LIB; goto err; } if (!BUF_MEM_grow_clean(&b,num+os->length)) { c->error=ERR_R_BUF_LIB; goto err; } memcpy(&(b.data[num]),os->data,os->length); if (!(c->inf & 1)) c->slen-=(c->p-c->q); num+=os->length; } if (!asn1_const_Finish(c)) goto err; a->length=num; if (a->data != NULL) OPENSSL_free(a->data); a->data=(unsigned char *)b.data; if (os != NULL) ASN1_STRING_free(os); return(1); err: OPENSSL_PUT_ERROR(ASN1, asn1_collate_primitive, c->error); if (os != NULL) ASN1_STRING_free(os); if (b.data != NULL) OPENSSL_free(b.data); return(0); }
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; } }
static int rsa_cms_encrypt(CMS_RecipientInfo *ri) { const EVP_MD *md, *mgf1md; RSA_OAEP_PARAMS *oaep = NULL; ASN1_STRING *os = NULL; X509_ALGOR *alg; EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; unsigned char *label; CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg); if (pkctx) { if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) return 0; } if (pad_mode == RSA_PKCS1_PADDING) { X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); return 1; } /* Not supported */ if (pad_mode != RSA_PKCS1_OAEP_PADDING) return 0; if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) goto err; if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) goto err; labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); if (labellen < 0) goto err; oaep = RSA_OAEP_PARAMS_new(); if (oaep == NULL) goto err; if (!rsa_md_to_algor(&oaep->hashFunc, md)) goto err; if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) goto err; if (labellen > 0) { ASN1_OCTET_STRING *los; oaep->pSourceFunc = X509_ALGOR_new(); if (oaep->pSourceFunc == NULL) goto err; los = ASN1_OCTET_STRING_new(); if (los == NULL) goto err; if (!ASN1_OCTET_STRING_set(los, label, labellen)) { ASN1_OCTET_STRING_free(los); goto err; } X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), V_ASN1_OCTET_STRING, los); } /* create string with pss parameter encoding. */ if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) goto err; X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); os = NULL; rv = 1; err: RSA_OAEP_PARAMS_free(oaep); ASN1_STRING_free(os); return rv; }
void CryptoNative_Asn1StringFree(ASN1_STRING* a) { ASN1_STRING_free(a); }