static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md, const char *policy, int no_nonce, int cert) { int ret = 0; TS_REQ *ts_req = NULL; int len; TS_MSG_IMPRINT *msg_imprint = NULL; X509_ALGOR *algo = NULL; unsigned char *data = NULL; ASN1_OBJECT *policy_obj = NULL; ASN1_INTEGER *nonce_asn1 = NULL; if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL) goto err; if ((ts_req = TS_REQ_new()) == NULL) goto err; if (!TS_REQ_set_version(ts_req, 1)) goto err; if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL) goto err; if ((algo = X509_ALGOR_new()) == NULL) goto err; if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL) goto err; if ((algo->parameter = ASN1_TYPE_new()) == NULL) goto err; algo->parameter->type = V_ASN1_NULL; if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err; if ((len = create_digest(data_bio, digest, md, &data)) == 0) goto err; if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err; if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err; if (policy && (policy_obj = txt2obj(policy)) == NULL) goto err; if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err; /* Setting nonce if requested. */ if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL) goto err; if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err; if (!TS_REQ_set_cert_req(ts_req, cert)) goto err; ret = 1; err: if (!ret) { TS_REQ_free(ts_req); ts_req = NULL; BIO_printf(bio_err, "could not create query\n"); ERR_print_errors(bio_err); } TS_MSG_IMPRINT_free(msg_imprint); X509_ALGOR_free(algo); OPENSSL_free(data); ASN1_OBJECT_free(policy_obj); ASN1_INTEGER_free(nonce_asn1); return ts_req; }
static CMS_EnvelopedData * cms_enveloped_data_init(CMS_ContentInfo *cms) { if (cms->d.other == NULL) { cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); if (!cms->d.envelopedData) { CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); return NULL; } cms->d.envelopedData->version = 0; cms->d.envelopedData->encryptedContentInfo->contentType = OBJ_nid2obj(NID_pkcs7_data); ASN1_OBJECT_free(cms->contentType); cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); return cms->d.envelopedData; } return cms_get0_enveloped(cms); }
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) { X509_CERT_AUX *aux; ASN1_OBJECT *objtmp = NULL; if (obj) { objtmp = OBJ_dup(obj); if (!objtmp) return 0; } if ((aux = aux_get(x)) == NULL) goto err; if (aux->trust == NULL && (aux->trust = sk_ASN1_OBJECT_new_null()) == NULL) goto err; if (!objtmp || sk_ASN1_OBJECT_push(aux->trust, objtmp)) return 1; err: ASN1_OBJECT_free(objtmp); return 0; }
static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { ASN1_OBJECT *obj = NULL; DSA *dsa = EVP_PKEY_get0(pkey); int nid; if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { return 0; } nid = OBJ_obj2nid(obj); ASN1_OBJECT_free(obj); if (!dsa) { dsa = DSA_new(); if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) return 0; } if (!fill_GOST94_params(dsa, nid)) return 0; return 1; }
void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) { if (!ctx) return; X509_STORE_free(ctx->store); sk_X509_pop_free(ctx->certs, X509_free); ASN1_OBJECT_free(ctx->policy); X509_ALGOR_free(ctx->md_alg); OPENSSL_free(ctx->imprint); BIO_free_all(ctx->data); ASN1_INTEGER_free(ctx->nonce); GENERAL_NAME_free(ctx->tsa_name); TS_VERIFY_CTX_init(ctx); }
static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { ASN1_OBJECT *obj = NULL; int nid; EC_KEY *ec = EVP_PKEY_get0(pkey); if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { return 0; } nid = OBJ_obj2nid(obj); ASN1_OBJECT_free(obj); if (!ec) { ec = EC_KEY_new(); if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) return 0; } if (!fill_GOST2001_params(ec, nid)) return 0; return 1; }
static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) { if (cms->d.other == NULL) { cms->d.signedData = M_ASN1_new_of(CMS_SignedData); if (!cms->d.signedData) { CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); return NULL; } cms->d.signedData->version = 1; cms->d.signedData->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); cms->d.signedData->encapContentInfo->partial = 1; ASN1_OBJECT_free(cms->contentType); cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); return cms->d.signedData; } return cms_get0_signed(cms); }
/* Create a generic extension: for now just handle DER type */ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, int crit, int type) { unsigned char *ext_der=NULL; long ext_len; ASN1_OBJECT *obj=NULL; ASN1_OCTET_STRING *oct=NULL; X509_EXTENSION *extension=NULL; if (!(obj = OBJ_txt2obj(ext, 0))) { X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_NAME_ERROR); ERR_add_error_data(2, "name=", ext); goto err; } if (!(ext_der = string_to_hex(value, &ext_len))) { X509V3err(X509V3_F_V3_GENERIC_EXTENSION,X509V3_R_EXTENSION_VALUE_ERROR); ERR_add_error_data(2, "value=", value); goto err; } if (!(oct = M_ASN1_OCTET_STRING_new())) { X509V3err(X509V3_F_V3_GENERIC_EXTENSION,ERR_R_MALLOC_FAILURE); goto err; } oct->data = ext_der; oct->length = ext_len; ext_der = NULL; extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); err: ASN1_OBJECT_free(obj); M_ASN1_OCTET_STRING_free(oct); if(ext_der) OPENSSL_free(ext_der); return extension; }
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, unsigned char **pp, long len) { ASN1_OBJECT *ret=NULL; unsigned char *p; int i; /* only the ASN1_OBJECTs from the 'table' will have values * for ->sn or ->ln */ if ((a == NULL) || ((*a) == NULL) || !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL); } else ret=(*a); p= *pp; if ((ret->data == NULL) || (ret->length < len)) { if (ret->data != NULL) OPENSSL_free(ret->data); ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; if (ret->data == NULL) { i=ERR_R_MALLOC_FAILURE; goto err; } } memcpy(ret->data,p,(int)len); ret->length=(int)len; ret->sn=NULL; ret->ln=NULL; /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ p+=len; if (a != NULL) (*a)=ret; *pp=p; return(ret); err: ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_OBJECT_free(ret); return(NULL); }
static int openssl_ts_req_policy_id(lua_State*L) { TS_REQ* req = CHECK_OBJECT(1, TS_REQ, "openssl.ts_req"); if (lua_isnone(L, 2)) { ASN1_OBJECT* obj = TS_REQ_get_policy_id(req); openssl_push_asn1object(L, obj); ASN1_OBJECT_free(obj); return 1; } else { int nid = openssl_get_nid(L, 2); ASN1_OBJECT* obj; int ret; luaL_argcheck(L, nid != NID_undef, 2, "must be asn1_object object identified"); obj = OBJ_nid2obj(nid); ret = TS_REQ_set_policy_id(req, obj); return openssl_pushresult(L, ret); } }
int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) { X509_CERT_AUX *aux; ASN1_OBJECT *objtmp; int rc; if (!(objtmp = OBJ_dup(obj))) return 0; if (!(aux = aux_get(x))) goto err; if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null())) goto err; rc = sk_ASN1_OBJECT_push(aux->reject, objtmp); if (rc != 0) return rc; err: ASN1_OBJECT_free(objtmp); 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; }
CRYPTO_PUBLIC_KEY * crypto_cert_get_public_key(CRYPTO_CERT * cert, uint32 * key_len) { #ifdef CRYPTO_OPENSSL int nid; CRYPTO_PUBLIC_KEY *lkey; EVP_PKEY *epk = NULL; /* For some reason, Microsoft sets the OID of the Public RSA key to the oid for "MD5 with RSA Encryption" instead of "RSA Encryption" Kudos to Richard Levitte for the following (intuitive) lines of code that resets the OID and lets us extract the key. */ nid = OBJ_obj2nid(cert->cert_info->key->algor->algorithm); if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption)) { ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm); cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); } epk = X509_get_pubkey(cert); if (NULL == epk) return NULL; lkey = RSAPublicKey_dup((RSA *) epk->pkey.ptr); *key_len = RSA_size(lkey); EVP_PKEY_free(epk); return lkey; #else /* built-in crypto */ return ssl_cert_get_public_key(cert, key_len); #endif }
static PyObject * get_extension (certificate_x509 *self, PyObject *args, PyObject *keywords) { const char *oid = NULL; const char *name = NULL; static char *keywordlist[] = { "oid", "name", NULL }; if (!PyArg_ParseTupleAndKeywords (args, keywords, "|ss", keywordlist, &oid, &name)) { return NULL; } char *value = NULL; size_t length; ASN1_OBJECT *obj = NULL; if (name != NULL) { obj = get_object_by_name (name); } else { obj = get_object_by_oid (oid); } if (obj == NULL) { Py_INCREF (Py_None); return Py_None; } length = get_extension_by_object (self->x509, obj, &value); ASN1_OBJECT_free (obj); if (value != NULL) { PyObject *extension = PyString_FromStringAndSize (value, length); free (value); return extension; } else { Py_INCREF (Py_None); return Py_None; } }
int has_voms_extension(const char *certfilepath) { ASN1_OBJECT *acseq_oid = NULL; X509 *cert = NULL; int position = -1; int result = -1; assert (certfilepath != NULL); acseq_oid = OBJ_txt2obj(ACSEQ_OID, 1); if (acseq_oid == NULL) { return result; } cert = load_X509_from_file(certfilepath); if (cert == NULL) { goto error; } position = X509_get_ext_by_OBJ(cert, acseq_oid, -1); if (position >= 0) { result = 1; } else { result = 0; } if (cert != NULL) { X509_free(cert); } error: if (acseq_oid != NULL) { ASN1_OBJECT_free(acseq_oid); } return result; }
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) { ASN1_OBJECT_free(alg->algorithm); alg->algorithm = aobj; } if (ptype == 0) return 1; if (ptype == V_ASN1_UNDEF) { ASN1_TYPE_free(alg->parameter); alg->parameter = NULL; } else ASN1_TYPE_set(alg->parameter, ptype, pval); return 1; }
int TS_CONF_set_def_policy(CONF *conf, const char *section, const char *policy, TS_RESP_CTX *ctx) { int ret = 0; ASN1_OBJECT *policy_obj = NULL; if (!policy) policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); if (!policy) { ts_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); goto err; } if ((policy_obj = OBJ_txt2obj(policy, 0)) == NULL) { ts_CONF_invalid(section, ENV_DEFAULT_POLICY); goto err; } if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) goto err; ret = 1; err: ASN1_OBJECT_free(policy_obj); return ret; }
int conv_eckey2gkey(EC_KEY *key, TANG_KEY_USE use, TANG_KEY *gkey, BN_CTX *ctx) { const EC_GROUP *grp = EC_KEY_get0_group(key); int r; if (!grp) return EINVAL; ASN1_OBJECT_free(gkey->grp); gkey->grp = OBJ_nid2obj(EC_GROUP_get_curve_name(grp)); if (!gkey->grp) return ENOMEM; r = conv_point2os(grp, EC_KEY_get0_public_key(key), gkey->key, ctx); if (r != 0) return ENOMEM; if (ASN1_ENUMERATED_set(gkey->use, use) <= 0) return ENOMEM; return 0; }
int GRSTasn1GetX509Name(char *x509name, int maxlength, char *coords, char *asn1string, struct GRSTasn1TagList taglist[], int lasttag) { int i, istr, n, len = 0; ASN1_OBJECT *obj = NULL; const char *shortname; int ret; for (i=1; ; ++i) { ret = GRSTasn1GetField(i, coords, asn1string, taglist, lasttag, &obj, &istr); if (ret) break; n = OBJ_obj2nid(obj); shortname = OBJ_nid2sn(n); ASN1_OBJECT_free(obj); obj = NULL; if (len + 2 + strlen(shortname) + taglist[istr].length >= maxlength) { x509name[0] = '\0'; return GRST_RET_FAILED; } sprintf(&x509name[len], "/%s=%.*s", shortname, taglist[istr].length, &asn1string[taglist[istr].start+taglist[istr].headerlength]); len += 2 + strlen(shortname) + taglist[istr].length; } x509name[len] = '\0'; return (x509name[0] != '\0') ? GRST_RET_OK : GRST_RET_FAILED; }
// retrieve the extended key usage for the cert LLSD _ext_key_usage_ext(X509* cert) { LLSD result; EXTENDED_KEY_USAGE *eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL); if(eku) { result = LLSD::emptyArray(); while(sk_ASN1_OBJECT_num(eku)) { ASN1_OBJECT *usage = sk_ASN1_OBJECT_pop(eku); if(usage) { int nid = OBJ_obj2nid(usage); if (nid) { std::string sn = OBJ_nid2sn(nid); result.append(sn); } ASN1_OBJECT_free(usage); } } } return result; }
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset, int depth, int indent, int dump) { const unsigned char *p, *ep, *tot, *op, *opp; long len; int tag, xclass, ret = 0; int nl, hl, j, r; ASN1_OBJECT *o = NULL; ASN1_OCTET_STRING *os = NULL; /* ASN1_BMPSTRING *bmp=NULL; */ int dump_indent, dump_cont = 0; if (depth > ASN1_PARSE_MAXDEPTH) { BIO_puts(bp, "BAD RECURSION DEPTH\n"); return 0; } dump_indent = 6; /* Because we know BIO_dump_indent() */ p = *pp; tot = p + length; while (length > 0) { op = p; j = ASN1_get_object(&p, &len, &tag, &xclass, length); if (j & 0x80) { if (BIO_write(bp, "Error in encoding\n", 18) <= 0) goto end; ret = 0; goto end; } hl = (p - op); length -= hl; /* * if j == 0x21 it is a constructed indefinite length object */ if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) <= 0) goto end; if (j != (V_ASN1_CONSTRUCTED | 1)) { if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", depth, (long)hl, len) <= 0) goto end; } else { if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) goto end; } if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) goto end; if (j & V_ASN1_CONSTRUCTED) { const unsigned char *sp = p; ep = p + len; if (BIO_write(bp, "\n", 1) <= 0) goto end; if (len > length) { BIO_printf(bp, "length is greater than %ld\n", length); ret = 0; goto end; } if ((j == 0x21) && (len == 0)) { for (;;) { r = asn1_parse2(bp, &p, (long)(tot - p), offset + (p - *pp), depth + 1, indent, dump); if (r == 0) { ret = 0; goto end; } if ((r == 2) || (p >= tot)) { len = p - sp; break; } } } else { long tmp = len; while (p < ep) { sp = p; r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1, indent, dump); if (r == 0) { ret = 0; goto end; } tmp -= p - sp; } } } else if (xclass != 0) { p += len; if (BIO_write(bp, "\n", 1) <= 0) goto end; } else { nl = 0; if ((tag == V_ASN1_PRINTABLESTRING) || (tag == V_ASN1_T61STRING) || (tag == V_ASN1_IA5STRING) || (tag == V_ASN1_VISIBLESTRING) || (tag == V_ASN1_NUMERICSTRING) || (tag == V_ASN1_UTF8STRING) || (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) { if (BIO_write(bp, ":", 1) <= 0) goto end; if ((len > 0) && BIO_write(bp, (const char *)p, (int)len) != (int)len) goto end; } else if (tag == V_ASN1_OBJECT) { opp = op; if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) { if (BIO_write(bp, ":", 1) <= 0) goto end; i2a_ASN1_OBJECT(bp, o); } else { if (BIO_puts(bp, ":BAD OBJECT") <= 0) goto end; dump_cont = 1; } } else if (tag == V_ASN1_BOOLEAN) { if (len != 1) { if (BIO_puts(bp, ":BAD BOOLEAN") <= 0) goto end; dump_cont = 1; } if (len > 0) BIO_printf(bp, ":%u", p[0]); } else if (tag == V_ASN1_BMPSTRING) { /* do the BMP thang */ } else if (tag == V_ASN1_OCTET_STRING) { int i, printable = 1; opp = op; os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl); if (os != NULL && os->length > 0) { opp = os->data; /* * testing whether the octet string is printable */ for (i = 0; i < os->length; i++) { if (((opp[i] < ' ') && (opp[i] != '\n') && (opp[i] != '\r') && (opp[i] != '\t')) || (opp[i] > '~')) { printable = 0; break; } } if (printable) /* printable string */ { if (BIO_write(bp, ":", 1) <= 0) goto end; if (BIO_write(bp, (const char *)opp, os->length) <= 0) goto end; } else if (!dump) /* * not printable => print octet string as hex dump */ { if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0) goto end; for (i = 0; i < os->length; i++) { if (BIO_printf(bp, "%02X", opp[i]) <= 0) goto end; } } else /* print the normal dump */ { if (!nl) { if (BIO_write(bp, "\n", 1) <= 0) goto end; } if (BIO_dump_indent(bp, (const char *)opp, ((dump == -1 || dump > os-> length) ? os->length : dump), dump_indent) <= 0) goto end; nl = 1; } } ASN1_OCTET_STRING_free(os); os = NULL; } else if (tag == V_ASN1_INTEGER) { ASN1_INTEGER *bs; int i; opp = op; bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); if (bs != NULL) { if (BIO_write(bp, ":", 1) <= 0) goto end; if (bs->type == V_ASN1_NEG_INTEGER) if (BIO_write(bp, "-", 1) <= 0) goto end; for (i = 0; i < bs->length; i++) { if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) goto end; } if (bs->length == 0) { if (BIO_write(bp, "00", 2) <= 0) goto end; } } else { if (BIO_puts(bp, ":BAD INTEGER") <= 0) goto end; dump_cont = 1; } ASN1_INTEGER_free(bs); } else if (tag == V_ASN1_ENUMERATED) { ASN1_ENUMERATED *bs; int i; opp = op; bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); if (bs != NULL) { if (BIO_write(bp, ":", 1) <= 0) goto end; if (bs->type == V_ASN1_NEG_ENUMERATED) if (BIO_write(bp, "-", 1) <= 0) goto end; for (i = 0; i < bs->length; i++) { if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) goto end; } if (bs->length == 0) { if (BIO_write(bp, "00", 2) <= 0) goto end; } } else { if (BIO_puts(bp, ":BAD ENUMERATED") <= 0) goto end; dump_cont = 1; } ASN1_ENUMERATED_free(bs); } else if (len > 0 && dump) { if (!nl) { if (BIO_write(bp, "\n", 1) <= 0) goto end; } if (BIO_dump_indent(bp, (const char *)p, ((dump == -1 || dump > len) ? len : dump), dump_indent) <= 0) goto end; nl = 1; } if (dump_cont) { int i; const unsigned char *tmp = op + hl; if (BIO_puts(bp, ":[") <= 0) goto end; for (i = 0; i < len; i++) { if (BIO_printf(bp, "%02X", tmp[i]) <= 0) goto end; } if (BIO_puts(bp, "]") <= 0) goto end; } if (!nl) { if (BIO_write(bp, "\n", 1) <= 0) goto end; } p += len; if ((tag == V_ASN1_EOC) && (xclass == 0)) { ret = 2; /* End of sequence */ goto end; } } length -= len; } ret = 1; end: ASN1_OBJECT_free(o); ASN1_OCTET_STRING_free(os); *pp = p; return (ret); }
static TokenError saveKeys(const CertReq *reqs, const char *hostname, const char *password, FILE *file) { TokenError error = TokenError_Unknown; PKCS12 *p12 = NULL; // Add PKCS7 safes with the keys STACK_OF(PKCS7) *authsafes = NULL; uint32_t localKeyId = 0; size_t error_count = 0; while (reqs) { STACK_OF(PKCS12_SAFEBAG) *bags = NULL; X509 *cert = NULL; ASN1_OBJECT *objOwningHost = NULL; uint32_t keyid = htonl(localKeyId++); bool success = false; // Add private key PKCS12_SAFEBAG *bag = PKCS12_add_key(&bags, reqs->privkey, opensslKeyUsages[reqs->pkcs10->keyUsage], ENC_ITER, ENC_NID, (char*)password); if (!bag) goto loop_end; // Add name and localKeyId to the key bag // TODO extract name from subject DN char *name = "names are not implemented yet"; if (!X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, MBSTRING_UTF8, (unsigned char*)name, strlen(name)) || !PKCS12_add_localkeyid(bag, (unsigned char*)&keyid, sizeof(keyid))) goto loop_end; // Add a certificate so we can find the key by the subject name cert = X509_REQ_to_X509(reqs->x509, 3650, reqs->privkey); if (!cert || !X509_keyid_set1(cert, (unsigned char*)&keyid, sizeof(keyid))) goto loop_end; if (!X509_add_ext(cert, makeKeyUsageExt(reqs->pkcs10->keyUsage), -1)) goto loop_end; if (!PKCS12_add_cert(&bags, cert)) goto loop_end; // Add hostname (FriBID extension) so we can do same-origin checks // TODO maybe we should use document.domain instead of document.location.hostname? objOwningHost = OBJ_txt2obj(OID_OWNING_HOST, 1); if (!objOwningHost) goto loop_end; bag = sk_PKCS12_SAFEBAG_value(bags, sk_PKCS12_SAFEBAG_num(bags)-1); if (!X509at_add1_attr_by_OBJ(&bag->attrib, objOwningHost, MBSTRING_UTF8, (unsigned char*)hostname, strlen(hostname))) goto loop_end; // Add a new authsafe if (!PKCS12_add_safe(&authsafes, bags, -1, 0, NULL)) goto loop_end; // Success! success = true; loop_end: if (!success) { error_count--; certutil_updateErrorString(); } ASN1_OBJECT_free(objOwningHost); X509_free(cert); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); reqs = reqs->next; } if (error_count != 0) goto end; // Create the PKCS12 wrapper p12 = PKCS12_add_safes(authsafes, 0); if (!p12) { certutil_updateErrorString(); goto end; } PKCS12_set_mac(p12, (char*)password, -1, NULL, 0, MAC_ITER, NULL); // Save file if (i2d_PKCS12_fp(file, p12)) { error = TokenError_Success; } end: sk_PKCS7_pop_free(authsafes, PKCS7_free); PKCS12_free(p12); return error; }
static void cleanup3(ADDED_OBJ *a) { if (--a->obj->nid == 0) ASN1_OBJECT_free(a->obj); OPENSSL_free(a); }
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, const EVP_MD *type) { EVP_MD_CTX ctx; unsigned char *p, *buf_in = NULL, *buf_out = NULL; int i, inl = 0, outl = 0, outll = 0; X509_ALGOR *a; EVP_MD_CTX_init(&ctx); for (i = 0; i < 2; i++) { if (i == 0) a = algor1; else a = algor2; if (a == NULL) continue; if (type->pkey_type == NID_dsaWithSHA1) { /* * special case: RFC 2459 tells us to omit 'parameters' with * id-dsa-with-sha1 */ ASN1_TYPE_free(a->parameter); a->parameter = NULL; } else if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); if ((a->parameter = ASN1_TYPE_new()) == NULL) goto err; a->parameter->type = V_ASN1_NULL; } ASN1_OBJECT_free(a->algorithm); a->algorithm = OBJ_nid2obj(type->pkey_type); if (a->algorithm == NULL) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); goto err; } if (a->algorithm->length == 0) { ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); goto err; } } inl = i2d(data, NULL); buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); outll = outl = EVP_PKEY_size(pkey); buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); if ((buf_in == NULL) || (buf_out == NULL)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); goto err; } p = buf_in; i2d(data, &p); if (!EVP_SignInit_ex(&ctx, type, NULL) || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, (unsigned int *)&outl, pkey)) { outl = 0; ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); goto err; } if (signature->data != NULL) OPENSSL_free(signature->data); signature->data = buf_out; buf_out = NULL; signature->length = outl; /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; err: EVP_MD_CTX_cleanup(&ctx); if (buf_in != NULL) { OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); OPENSSL_free(buf_in); } if (buf_out != NULL) { OPENSSL_cleanse((char *)buf_out, outll); OPENSSL_free(buf_out); } return (outl); }
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { X509_PUBKEY *pk=NULL; X509_ALGOR *a; ASN1_OBJECT *o; unsigned char *s,*p = NULL; int i; if (x == NULL) return(0); if ((pk=X509_PUBKEY_new()) == NULL) goto err; a=pk->algor; /* set the algorithm id */ if ((o=OBJ_nid2obj(pkey->type)) == NULL) goto err; ASN1_OBJECT_free(a->algorithm); a->algorithm=o; /* Set the parameter list */ if (!pkey->save_parameters || (pkey->type == EVP_PKEY_RSA)) { if ((a->parameter == NULL) || (a->parameter->type != V_ASN1_NULL)) { ASN1_TYPE_free(a->parameter); if (!(a->parameter=ASN1_TYPE_new())) { X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } a->parameter->type=V_ASN1_NULL; } } #ifndef OPENSSL_NO_DSA else if (pkey->type == EVP_PKEY_DSA) { unsigned char *pp; DSA *dsa; dsa=pkey->pkey.dsa; dsa->write_params=0; ASN1_TYPE_free(a->parameter); if ((i=i2d_DSAparams(dsa,NULL)) <= 0) goto err; if (!(p=(unsigned char *)OPENSSL_malloc(i))) { X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } pp=p; i2d_DSAparams(dsa,&pp); if (!(a->parameter=ASN1_TYPE_new())) { OPENSSL_free(p); X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } a->parameter->type=V_ASN1_SEQUENCE; if (!(a->parameter->value.sequence=ASN1_STRING_new())) { OPENSSL_free(p); X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } if (!ASN1_STRING_set(a->parameter->value.sequence,p,i)) { OPENSSL_free(p); X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_free(p); } #endif #ifndef OPENSSL_NO_EC else if (pkey->type == EVP_PKEY_EC) { int nid=0; unsigned char *pp; EC_KEY *ec_key; const EC_GROUP *group; ec_key = pkey->pkey.ec; ASN1_TYPE_free(a->parameter); if ((a->parameter = ASN1_TYPE_new()) == NULL) { X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); goto err; } group = EC_KEY_get0_group(ec_key); if (EC_GROUP_get_asn1_flag(group) && (nid = EC_GROUP_get_curve_name(group))) { /* just set the OID */ a->parameter->type = V_ASN1_OBJECT; a->parameter->value.object = OBJ_nid2obj(nid); } else /* explicit parameters */ { if ((i = i2d_ECParameters(ec_key, NULL)) == 0) { X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); goto err; } if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) { X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE); goto err; } pp = p; if (!i2d_ECParameters(ec_key, &pp)) { X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB); OPENSSL_free(p); goto err; } a->parameter->type = V_ASN1_SEQUENCE; if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) { X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); OPENSSL_free(p); goto err; } ASN1_STRING_set(a->parameter->value.sequence, p, i); OPENSSL_free(p); } } #endif else if (1) { X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); goto err; } if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err; if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) { X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } p=s; i2d_PublicKey(pkey,&p); if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) { X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); goto err; } /* Set number of unused bits to zero */ pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; OPENSSL_free(s); #if 0 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); pk->pkey=pkey; #endif if (*x != NULL) X509_PUBKEY_free(*x); *x=pk; return 1; err: if (pk != NULL) X509_PUBKEY_free(pk); return 0; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *signerfile = NULL, *recipfile = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL; char *certsoutfile = NULL; const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; int badarg = 0; int flags = CMS_DETACHED, noout = 0, print = 0; int verify_retcode = 0; int rr_print = 0, rr_allorfirst = -1; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; CMS_ReceiptRequest *rr = NULL; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; const EVP_MD *sign_md = NULL; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; # ifndef OPENSSL_NO_ENGINE char *engine = NULL; # endif unsigned char *secret_key = NULL, *secret_keyid = NULL; unsigned char *pwri_pass = NULL, *pwri_tmp = NULL; size_t secret_keylen = 0, secret_keyidlen = 0; cms_key_param *key_first = NULL, *key_param = NULL; ASN1_OBJECT *econtent_type = NULL; X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp(*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp(*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp(*args, "-sign_receipt")) operation = SMIME_SIGN_RECEIPT; else if (!strcmp(*args, "-resign")) operation = SMIME_RESIGN; else if (!strcmp(*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp(*args, "-verify_retcode")) verify_retcode = 1; else if (!strcmp(*args, "-verify_receipt")) { operation = SMIME_VERIFY_RECEIPT; if (!args[1]) goto argerr; args++; rctfile = *args; } else if (!strcmp(*args, "-cmsout")) operation = SMIME_CMSOUT; else if (!strcmp(*args, "-data_out")) operation = SMIME_DATAOUT; else if (!strcmp(*args, "-data_create")) operation = SMIME_DATA_CREATE; else if (!strcmp(*args, "-digest_verify")) operation = SMIME_DIGEST_VERIFY; else if (!strcmp(*args, "-digest_create")) operation = SMIME_DIGEST_CREATE; else if (!strcmp(*args, "-compress")) operation = SMIME_COMPRESS; else if (!strcmp(*args, "-uncompress")) operation = SMIME_UNCOMPRESS; else if (!strcmp(*args, "-EncryptedData_decrypt")) operation = SMIME_ENCRYPTED_DECRYPT; else if (!strcmp(*args, "-EncryptedData_encrypt")) operation = SMIME_ENCRYPTED_ENCRYPT; # ifndef OPENSSL_NO_DES else if (!strcmp(*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp(*args, "-des")) cipher = EVP_des_cbc(); else if (!strcmp(*args, "-des3-wrap")) wrap_cipher = EVP_des_ede3_wrap(); # endif # ifndef OPENSSL_NO_SEED else if (!strcmp(*args, "-seed")) cipher = EVP_seed_cbc(); # endif # ifndef OPENSSL_NO_RC2 else if (!strcmp(*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp(*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp(*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); # endif # ifndef OPENSSL_NO_AES else if (!strcmp(*args, "-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args, "-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args, "-aes256")) cipher = EVP_aes_256_cbc(); else if (!strcmp(*args, "-aes128-wrap")) wrap_cipher = EVP_aes_128_wrap(); else if (!strcmp(*args, "-aes192-wrap")) wrap_cipher = EVP_aes_192_wrap(); else if (!strcmp(*args, "-aes256-wrap")) wrap_cipher = EVP_aes_256_wrap(); # endif # ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args, "-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args, "-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args, "-camellia256")) cipher = EVP_camellia_256_cbc(); # endif else if (!strcmp(*args, "-debug_decrypt")) flags |= CMS_DEBUG_DECRYPT; else if (!strcmp(*args, "-text")) flags |= CMS_TEXT; else if (!strcmp(*args, "-nointern")) flags |= CMS_NOINTERN; else if (!strcmp(*args, "-noverify") || !strcmp(*args, "-no_signer_cert_verify")) flags |= CMS_NO_SIGNER_CERT_VERIFY; else if (!strcmp(*args, "-nocerts")) flags |= CMS_NOCERTS; else if (!strcmp(*args, "-noattr")) flags |= CMS_NOATTR; else if (!strcmp(*args, "-nodetach")) flags &= ~CMS_DETACHED; else if (!strcmp(*args, "-nosmimecap")) flags |= CMS_NOSMIMECAP; else if (!strcmp(*args, "-binary")) flags |= CMS_BINARY; else if (!strcmp(*args, "-keyid")) flags |= CMS_USE_KEYID; else if (!strcmp(*args, "-nosigs")) flags |= CMS_NOSIGS; else if (!strcmp(*args, "-no_content_verify")) flags |= CMS_NO_CONTENT_VERIFY; else if (!strcmp(*args, "-no_attr_verify")) flags |= CMS_NO_ATTR_VERIFY; else if (!strcmp(*args, "-stream")) flags |= CMS_STREAM; else if (!strcmp(*args, "-indef")) flags |= CMS_STREAM; else if (!strcmp(*args, "-noindef")) flags &= ~CMS_STREAM; else if (!strcmp(*args, "-nooldmime")) flags |= CMS_NOOLDMIMETYPE; else if (!strcmp(*args, "-crlfeol")) flags |= CMS_CRLFEOL; else if (!strcmp(*args, "-noout")) noout = 1; else if (!strcmp(*args, "-receipt_request_print")) rr_print = 1; else if (!strcmp(*args, "-receipt_request_all")) rr_allorfirst = 0; else if (!strcmp(*args, "-receipt_request_first")) rr_allorfirst = 1; else if (!strcmp(*args, "-receipt_request_from")) { if (!args[1]) goto argerr; args++; if (!rr_from) rr_from = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_from, *args); } else if (!strcmp(*args, "-receipt_request_to")) { if (!args[1]) goto argerr; args++; if (!rr_to) rr_to = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_to, *args); } else if (!strcmp(*args, "-print")) { noout = 1; print = 1; } else if (!strcmp(*args, "-secretkey")) { long ltmp; if (!args[1]) goto argerr; args++; secret_key = string_to_hex(*args, <mp); if (!secret_key) { BIO_printf(bio_err, "Invalid key %s\n", *args); goto argerr; } secret_keylen = (size_t)ltmp; } else if (!strcmp(*args, "-secretkeyid")) { long ltmp; if (!args[1]) goto argerr; args++; secret_keyid = string_to_hex(*args, <mp); if (!secret_keyid) { BIO_printf(bio_err, "Invalid id %s\n", *args); goto argerr; } secret_keyidlen = (size_t)ltmp; } else if (!strcmp(*args, "-pwri_password")) { if (!args[1]) goto argerr; args++; pwri_pass = (unsigned char *)*args; } else if (!strcmp(*args, "-econtent_type")) { if (!args[1]) goto argerr; args++; econtent_type = OBJ_txt2obj(*args, 0); if (!econtent_type) { BIO_printf(bio_err, "Invalid OID %s\n", *args); goto argerr; } } else if (!strcmp(*args, "-rand")) { if (!args[1]) goto argerr; args++; inrand = *args; need_rand = 1; } # ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args, "-engine")) { if (!args[1]) goto argerr; engine = *++args; } # endif else if (!strcmp(*args, "-passin")) { if (!args[1]) goto argerr; passargin = *++args; } else if (!strcmp(*args, "-to")) { if (!args[1]) goto argerr; to = *++args; } else if (!strcmp(*args, "-from")) { if (!args[1]) goto argerr; from = *++args; } else if (!strcmp(*args, "-subject")) { if (!args[1]) goto argerr; subject = *++args; } else if (!strcmp(*args, "-signer")) { if (!args[1]) goto argerr; /* If previous -signer argument add signer to list */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!keyfile) keyfile = signerfile; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = *++args; } else if (!strcmp(*args, "-recip")) { if (!args[1]) goto argerr; if (operation == SMIME_ENCRYPT) { if (!encerts) encerts = sk_X509_new_null(); cert = load_cert(bio_err, *++args, FORMAT_PEM, NULL, e, "recipient certificate file"); if (!cert) goto end; sk_X509_push(encerts, cert); cert = NULL; } else recipfile = *++args; } else if (!strcmp(*args, "-certsout")) { if (!args[1]) goto argerr; certsoutfile = *++args; } else if (!strcmp(*args, "-md")) { if (!args[1]) goto argerr; sign_md = EVP_get_digestbyname(*++args); if (sign_md == NULL) { BIO_printf(bio_err, "Unknown digest %s\n", *args); goto argerr; } } else if (!strcmp(*args, "-inkey")) { if (!args[1]) goto argerr; /* If previous -inkey arument add signer to list */ if (keyfile) { if (!signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = *++args; } else if (!strcmp(*args, "-keyform")) { if (!args[1]) goto argerr; keyform = str2fmt(*++args); } else if (!strcmp(*args, "-keyopt")) { int keyidx = -1; if (!args[1]) goto argerr; if (operation == SMIME_ENCRYPT) { if (encerts) keyidx += sk_X509_num(encerts); } else { if (keyfile || signerfile) keyidx++; if (skkeys) keyidx += sk_OPENSSL_STRING_num(skkeys); } if (keyidx < 0) { BIO_printf(bio_err, "No key specified\n"); goto argerr; } if (key_param == NULL || key_param->idx != keyidx) { cms_key_param *nparam; nparam = OPENSSL_malloc(sizeof(cms_key_param)); if (!nparam) { BIO_printf(bio_err, "Out of memory\n"); goto argerr; } nparam->idx = keyidx; nparam->param = sk_OPENSSL_STRING_new_null(); nparam->next = NULL; if (key_first == NULL) key_first = nparam; else key_param->next = nparam; key_param = nparam; } sk_OPENSSL_STRING_push(key_param->param, *++args); } else if (!strcmp(*args, "-rctform")) { if (!args[1]) goto argerr; rctformat = str2fmt(*++args); } else if (!strcmp(*args, "-certfile")) { if (!args[1]) goto argerr; certfile = *++args; } else if (!strcmp(*args, "-CAfile")) { if (!args[1]) goto argerr; CAfile = *++args; } else if (!strcmp(*args, "-CApath")) { if (!args[1]) goto argerr; CApath = *++args; } else if (!strcmp(*args, "-in")) { if (!args[1]) goto argerr; infile = *++args; } else if (!strcmp(*args, "-inform")) { if (!args[1]) goto argerr; informat = str2fmt(*++args); } else if (!strcmp(*args, "-outform")) { if (!args[1]) goto argerr; outformat = str2fmt(*++args); } else if (!strcmp(*args, "-out")) { if (!args[1]) goto argerr; outfile = *++args; } else if (!strcmp(*args, "-content")) { if (!args[1]) goto argerr; contfile = *++args; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) badarg = 1; args++; } if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto argerr; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } /* Check to see if any final signer needs to be appended */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile && !secret_key && !pwri_pass) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args && !secret_key && !pwri_pass && !encerts) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { argerr: BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-encrypt encrypt message\n"); BIO_printf(bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf(bio_err, "-sign sign message\n"); BIO_printf(bio_err, "-verify verify signed message\n"); BIO_printf(bio_err, "-cmsout output CMS structure\n"); # ifndef OPENSSL_NO_DES BIO_printf(bio_err, "-des3 encrypt with triple DES\n"); BIO_printf(bio_err, "-des encrypt with DES\n"); # endif # ifndef OPENSSL_NO_SEED BIO_printf(bio_err, "-seed encrypt with SEED\n"); # endif # ifndef OPENSSL_NO_RC2 BIO_printf(bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf(bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf(bio_err, "-rc2-128 encrypt with RC2-128\n"); # endif # ifndef OPENSSL_NO_AES BIO_printf(bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc aes\n"); # endif # ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err, " encrypt PEM output with cbc camellia\n"); # endif BIO_printf(bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf(bio_err, "-nosigs don't verify message signature\n"); BIO_printf(bio_err, "-noverify don't verify signers certificate\n"); BIO_printf(bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf(bio_err, "-nodetach use opaque signing\n"); BIO_printf(bio_err, "-noattr don't include any signed attributes\n"); BIO_printf(bio_err, "-binary don't translate message to text\n"); BIO_printf(bio_err, "-certfile file other certificates file\n"); BIO_printf(bio_err, "-certsout file certificate output file\n"); BIO_printf(bio_err, "-signer file signer certificate file\n"); BIO_printf(bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf(bio_err, "-keyid use subject key identifier\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf(bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf(bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf(bio_err, "-keyopt nm:v set public key parameters\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf(bio_err, "-content file supply or override content for detached signature\n"); BIO_printf(bio_err, "-to addr to address\n"); BIO_printf(bio_err, "-from ad from address\n"); BIO_printf(bio_err, "-subject s subject\n"); BIO_printf(bio_err, "-text include or delete text MIME headers\n"); BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); BIO_printf(bio_err, "-trusted_first use trusted certificates first when building the trust chain\n"); BIO_printf(bio_err, "-no_alt_chains only ever use the first certificate chain found\n"); BIO_printf(bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf(bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); # ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); # endif BIO_printf(bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf(bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } # ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); # endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (!(operation & SMIME_SIGNERS)) flags &= ~CMS_DETACHED; if (operation & SMIME_OP) { if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & CMS_BINARY) outmode = "wb"; } if (operation & SMIME_IP) { if (informat == FORMAT_ASN1) inmode = "rb"; } else { if (flags & CMS_BINARY) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { # ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); # else BIO_printf(bio_err, "No cipher selected\n"); goto end; # endif } if (secret_key && !secret_keyid) { BIO_printf(bio_err, "No secret key id\n"); goto end; } if (*args && !encerts) encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err, *args, FORMAT_PEM, NULL, e, "recipient certificate file"))) goto end; sk_X509_push(encerts, cert); cert = NULL; args++; } } if (certfile) { if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_SIGN_RECEIPT) { if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, e, "receipt signer certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf(bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) cms = SMIME_read_CMS(in, &indata); else if (informat == FORMAT_PEM) cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) cms = d2i_CMS_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for CMS file\n"); goto end; } if (!cms) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } if (certsoutfile) { STACK_OF(X509) *allcerts; allcerts = CMS_get1_certs(cms); if (!save_certs(certsoutfile, allcerts)) { BIO_printf(bio_err, "Error writing certs to %s\n", certsoutfile); ret = 5; goto end; } sk_X509_pop_free(allcerts, X509_free); } } if (rctfile) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; if (!(rctin = BIO_new_file(rctfile, rctmode))) { BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile); goto end; } if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) rcms = d2i_CMS_bio(rctin, NULL); else { BIO_printf(bio_err, "Bad input format for receipt\n"); goto end; } if (!rcms) { BIO_printf(bio_err, "Error reading receipt\n"); goto end; } } if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); # ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } # endif } if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_DATA_CREATE) { cms = CMS_data_create(in, flags); } else if (operation == SMIME_DIGEST_CREATE) { cms = CMS_digest_create(in, sign_md, flags); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { int i; flags |= CMS_PARTIAL; cms = CMS_encrypt(NULL, in, cipher, flags); if (!cms) goto end; for (i = 0; i < sk_X509_num(encerts); i++) { CMS_RecipientInfo *ri; cms_key_param *kparam; int tflags = flags; X509 *x = sk_X509_value(encerts, i); for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; break; } } ri = CMS_add1_recipient_cert(cms, x, tflags); if (!ri) goto end; if (kparam) { EVP_PKEY_CTX *pctx; pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE && wrap_cipher) { EVP_CIPHER_CTX *wctx; wctx = CMS_RecipientInfo_kari_get0_ctx(ri); EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL); } } if (secret_key) { if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, secret_keylen, secret_keyid, secret_keyidlen, NULL, NULL, NULL)) goto end; /* NULL these because call absorbs them */ secret_key = NULL; secret_keyid = NULL; } if (pwri_pass) { pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass); if (!pwri_tmp) goto end; if (!CMS_add0_recipient_password(cms, -1, NID_undef, NID_undef, pwri_tmp, -1, NULL)) goto end; pwri_tmp = NULL; } if (!(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, secret_keylen, flags); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; STACK_OF(CMS_SignerInfo) *sis; CMS_SignerInfo *si; sis = CMS_get0_SignerInfos(cms); if (!sis) goto end; si = sk_CMS_SignerInfo_value(sis, 0); srcms = CMS_sign_receipt(si, signer, key, other, flags); if (!srcms) goto end; CMS_ContentInfo_free(cms); cms = srcms; } else if (operation & SMIME_SIGNERS) { int i; /* * If detached data content we enable streaming if S/MIME output * format. */ if (operation == SMIME_SIGN) { if (flags & CMS_DETACHED) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; cms = CMS_sign(NULL, NULL, other, in, flags); if (!cms) goto end; if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if (rr_to) { rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); if (!rr) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); goto end; } } } else flags |= CMS_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; cms_key_param *kparam; int tflags = flags; signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; for (kparam = key_first; kparam; kparam = kparam->next) { if (kparam->idx == i) { tflags |= CMS_KEY_PARAM; break; } } si = CMS_add1_signer(cms, signer, key, sign_md, tflags); if (!si) goto end; if (kparam) { EVP_PKEY_CTX *pctx; pctx = CMS_SignerInfo_get0_pkey_ctx(si); if (!cms_set_pkey_param(pctx, kparam->param)) goto end; } if (rr && !CMS_add1_ReceiptRequest(si, rr)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } if (!cms) { BIO_printf(bio_err, "Error creating CMS structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (flags & CMS_DEBUG_DECRYPT) CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); if (secret_key) { if (!CMS_decrypt_set1_key(cms, secret_key, secret_keylen, secret_keyid, secret_keyidlen)) { BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); goto end; } } if (key) { if (!CMS_decrypt_set1_pkey(cms, key, recip)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } } if (pwri_pass) { if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) { BIO_puts(bio_err, "Error decrypting CMS using password\n"); goto end; } } if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } } else if (operation == SMIME_DATAOUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { if (!CMS_uncompress(cms, indata, out, flags)) goto end; } else if (operation == SMIME_DIGEST_VERIFY) { if (CMS_digest_verify(cms, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else if (operation == SMIME_ENCRYPTED_DECRYPT) { if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, indata, out, flags)) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile) { STACK_OF(X509) *signers; signers = CMS_get0_signers(cms); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } if (rr_print) receipt_request_print(bio_err, cms); } else if (operation == SMIME_VERIFY_RECEIPT) { if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else { if (noout) { if (print) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) ret = i2d_CMS_bio_stream(out, cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); goto end; } if (ret <= 0) { ret = 6; goto end; } } ret = 0; end: if (ret) ERR_print_errors(bio_err); if (need_rand) app_RAND_write_file(NULL, bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); if (sksigners) sk_OPENSSL_STRING_free(sksigners); if (skkeys) sk_OPENSSL_STRING_free(skkeys); if (secret_key) OPENSSL_free(secret_key); if (secret_keyid) OPENSSL_free(secret_keyid); if (pwri_tmp) OPENSSL_free(pwri_tmp); if (econtent_type) ASN1_OBJECT_free(econtent_type); if (rr) CMS_ReceiptRequest_free(rr); if (rr_to) sk_OPENSSL_STRING_free(rr_to); if (rr_from) sk_OPENSSL_STRING_free(rr_from); for (key_param = key_first; key_param;) { cms_key_param *tparam; sk_OPENSSL_STRING_free(key_param->param); tparam = key_param->next; OPENSSL_free(key_param); key_param = tparam; } X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); BIO_free(rctin); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey) { EC_KEY *ec_key; const EC_GROUP *group; unsigned char *p, *pp; int nid, i, ret = 0; unsigned int tmp_flags, old_flags; ec_key = pkey->pkey.ec; if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS); return 0; } /* set the ec parameters OID */ if (p8->pkeyalg->algorithm) ASN1_OBJECT_free(p8->pkeyalg->algorithm); p8->pkeyalg->algorithm = OBJ_nid2obj(NID_X9_62_id_ecPublicKey); /* set the ec parameters */ if (p8->pkeyalg->parameter) { ASN1_TYPE_free(p8->pkeyalg->parameter); p8->pkeyalg->parameter = NULL; } if ((p8->pkeyalg->parameter = ASN1_TYPE_new()) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } if (EC_GROUP_get_asn1_flag(group) && (nid = EC_GROUP_get_curve_name(group))) { /* we have a 'named curve' => just set the OID */ p8->pkeyalg->parameter->type = V_ASN1_OBJECT; p8->pkeyalg->parameter->value.object = OBJ_nid2obj(nid); } else /* explicit parameters */ { if ((i = i2d_ECParameters(ec_key, NULL)) == 0) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); return 0; } if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } pp = p; if (!i2d_ECParameters(ec_key, &pp)) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); OPENSSL_free(p); return 0; } p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE; if ((p8->pkeyalg->parameter->value.sequence = ASN1_STRING_new()) == NULL) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_ASN1_LIB); OPENSSL_free(p); return 0; } ASN1_STRING_set(p8->pkeyalg->parameter->value.sequence, p, i); OPENSSL_free(p); } /* set the private key */ /* do not include the parameters in the SEC1 private key * see PKCS#11 12.11 */ old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec); tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags); i = i2d_ECPrivateKey(pkey->pkey.ec, NULL); if (!i) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); return 0; } p = (unsigned char *) OPENSSL_malloc(i); if (!p) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); return 0; } pp = p; if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp)) { EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB); OPENSSL_free(p); return 0; } /* restore old encoding flags */ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags); switch(p8->broken) { case PKCS8_OK: p8->pkey->value.octet_string = ASN1_OCTET_STRING_new(); if (!p8->pkey->value.octet_string || !M_ASN1_OCTET_STRING_set(p8->pkey->value.octet_string, (const void *)p, i)) { EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE); } else ret = 1; break; case PKCS8_NO_OCTET: /* RSA specific */ case PKCS8_NS_DB: /* DSA specific */ case PKCS8_EMBEDDED_PARAM: /* DSA specific */ default: EVPerr(EVP_F_ECKEY_PKEY2PKCS8,EVP_R_ENCODE_ERROR); } OPENSSL_cleanse(p, (size_t)i); OPENSSL_free(p); return ret; }
static void policy_map_free(X509_POLICY_REF *map) { if (map->subjectDomainPolicy) ASN1_OBJECT_free(map->subjectDomainPolicy); OPENSSL_free(map); }
ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len) { ASN1_OBJECT *ret = NULL; const unsigned char *p; unsigned char *data; int i, length; /* * Sanity check OID encoding: * - need at least one content octet * - MSB must be clear in the last octet * - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2 */ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || p[len - 1] & 0x80) { ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); return (NULL); } /* Now 0 < len <= INT_MAX, so the cast is safe. */ length = (int)len; for (i = 0; i < length; i++, p++) { if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); return NULL; } } /* only the ASN1_OBJECTs from the 'table' will have values * for ->sn or ->ln */ if ((a == NULL) || ((*a) == NULL) || !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { if ((ret = ASN1_OBJECT_new()) == NULL) return (NULL); } else ret = (*a); p = *pp; /* detach data from object */ data = (unsigned char *)ret->data; ret->data = NULL; /* once detached we can change it */ if ((data == NULL) || (ret->length < length)) { ret->length = 0; free(data); data = malloc(length); if (data == NULL) { i = ERR_R_MALLOC_FAILURE; goto err; } ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; } memcpy(data, p, length); /* reattach data to object, after which it remains const */ ret->data = data; ret->length = length; ret->sn = NULL; ret->ln = NULL; /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ p += length; if (a != NULL) (*a) = ret; *pp = p; return (ret); err: ASN1err(ASN1_F_C2I_ASN1_OBJECT, i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_OBJECT_free(ret); return (NULL); }
int ccn_verify_signature(const unsigned char *msg, size_t size, const struct ccn_parsed_ContentObject *co, const struct ccn_pkey *verification_pubkey) { EVP_MD_CTX verc; EVP_MD_CTX *ver_ctx = &verc; X509_SIG *digest_info = NULL; MP_info *merkle_path_info = NULL; unsigned char *root_hash; size_t root_hash_size; int res; const EVP_MD *digest = EVP_md_null(); const EVP_MD *merkle_path_digest = EVP_md_null(); const unsigned char *signature_bits = NULL; size_t signature_bits_size = 0; const unsigned char *witness = NULL; size_t witness_size = 0; EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey; #ifdef DEBUG int x, h; #endif res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, msg, co->offset[CCN_PCO_B_SignatureBits], co->offset[CCN_PCO_E_SignatureBits], &signature_bits, &signature_bits_size); if (res < 0) return (-1); if (co->offset[CCN_PCO_B_DigestAlgorithm] == co->offset[CCN_PCO_E_DigestAlgorithm]) { digest = EVP_sha256(); } else { /* XXX - figure out what algorithm the OID represents */ fprintf(stderr, "not a DigestAlgorithm I understand right now\n"); return (-1); } EVP_MD_CTX_init(ver_ctx); res = EVP_VerifyInit_ex(ver_ctx, digest, NULL); if (!res) return (-1); if (co->offset[CCN_PCO_B_Witness] != co->offset[CCN_PCO_E_Witness]) { /* The witness is a DigestInfo, where the octet-string therein encapsulates * a sequence of [integer (origin 1 node#), sequence of [octet-string]] * where the inner octet-string is the concatenated hashes on the merkle-path */ res = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, msg, co->offset[CCN_PCO_B_Witness], co->offset[CCN_PCO_E_Witness], &witness, &witness_size); if (res < 0) return (-1); digest_info = d2i_X509_SIG(NULL, &witness, witness_size); /* digest_info->algor->algorithm->{length, data} * digest_info->digest->{length, type, data} */ /* ...2.2 is an MHT w/ SHA256 */ ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1); if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) { fprintf(stderr, "A witness is present without an MHT OID!\n"); ASN1_OBJECT_free(merkle_hash_tree_oid); return (-1); } /* we're doing an MHT */ ASN1_OBJECT_free(merkle_hash_tree_oid); merkle_path_digest = EVP_sha256(); /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */ merkle_path_info = d2i_MP_info(NULL, (const unsigned char **)&(digest_info->digest->data), digest_info->digest->length); #ifdef DEBUG int node = ASN1_INTEGER_get(merkle_path_info->node); int hash_count = merkle_path_info->hashes->num; ASN1_OCTET_STRING *hash; fprintf(stderr, "A witness is present with an MHT OID\n"); fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count); for (h = 0; h < hash_count; h++) { hash = (ASN1_OCTET_STRING *)merkle_path_info->hashes->data[h]; fprintf(stderr, " hashes[%d] len = %d data = ", h, hash->length); for (x = 0; x < hash->length; x++) { fprintf(stderr, "%02x", hash->data[x]); } fprintf(stderr, "\n"); } #endif /* In the MHT signature case, we signed/verify the root hash */ root_hash_size = EVP_MD_size(merkle_path_digest); root_hash = calloc(1, root_hash_size); res = ccn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size); res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size); res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } else { /* * In the simple signature case, we signed/verify from the name through * the end of the content. */ size_t signed_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name]; res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[CCN_PCO_B_Name], signed_size); res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey); EVP_MD_CTX_cleanup(ver_ctx); } if (res == 1) return (1); else return (0); }