void pki_x509req::createReq(pki_key *key, const x509name &dn, const EVP_MD *md, extList el) { int bad_nids[] = { NID_subject_key_identifier, NID_authority_key_identifier, NID_issuer_alt_name, NID_undef }; EVP_PKEY *privkey = NULL; if (key->isPubKey()) { my_error(tr("Signing key not valid (public key)")); return; } X509_REQ_set_version(request, 0L); X509_REQ_set_pubkey(request, key->getPubKey()); setSubject(dn); pki_openssl_error(); for(int i=0; bad_nids[i] != NID_undef; i++) el.delByNid(bad_nids[i]); el.delInvalid(); if (el.count() > 0) { STACK_OF(X509_EXTENSION) *sk; sk = el.getStack(); X509_REQ_add_extensions(request, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); } pki_openssl_error(); privkey = key->decryptKey(); X509_REQ_sign(request, privkey, md); pki_openssl_error(); EVP_PKEY_free(privkey); }
void TS_REQ_ext_free(TS_REQ *a) { if (!a) return; sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); a->extensions = NULL; }
static int openssl_crl_extensions(lua_State* L) { X509_CRL *crl = CHECK_OBJECT(1, X509_CRL, "openssl.x509_crl"); if (lua_isnone(L, 2)) { STACK_OF(X509_EXTENSION) *exts = crl->crl->extensions; if (exts) { openssl_sk_x509_extension_totable(L, exts); } else lua_pushnil(L); return 1; } else { STACK_OF(X509_EXTENSION) *exts = openssl_sk_x509_extension_fromtable(L, 2); int i, n; n = sk_X509_EXTENSION_num(exts); for (i = 0; i < n; i++) { X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); X509_CRL_add_ext(crl, X509_EXTENSION_dup(ext), i); }; sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); return openssl_pushresult(L, 1); } }
/* * Sets X509_EXTENSIONs */ static VALUE ossl_x509crl_set_extensions(VALUE self, VALUE ary) { X509_CRL *crl; X509_EXTENSION *ext; int i; Check_Type(ary, T_ARRAY); /* All ary members should be X509 Extensions */ for (i=0; i<RARRAY_LEN(ary); i++) { OSSL_Check_Kind(RARRAY_PTR(ary)[i], cX509Ext); } GetX509CRL(self, crl); sk_X509_EXTENSION_pop_free(crl->crl->extensions, X509_EXTENSION_free); crl->crl->extensions = NULL; for (i=0; i<RARRAY_LEN(ary); i++) { ext = DupX509ExtPtr(RARRAY_PTR(ary)[i]); if(!X509_CRL_add_ext(crl, ext, -1)) { /* DUPs ext - FREE it */ X509_EXTENSION_free(ext); ossl_raise(eX509CRLError, NULL); } X509_EXTENSION_free(ext); } return ary; }
static LUA_FUNCTION(openssl_csr_parse) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); X509_NAME * subject = X509_REQ_get_subject_name(csr); STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); lua_newtable(L); openssl_push_asn1(L, csr->signature, V_ASN1_BIT_STRING); lua_setfield(L, -2, "signature"); openssl_push_x509_algor(L, csr->sig_alg); lua_setfield(L, -2, "sig_alg"); lua_newtable(L); AUXILIAR_SET(L, -1, "version", X509_REQ_get_version(csr), integer); openssl_push_xname_asobject(L, subject); lua_setfield(L, -2, "subject"); if (exts) { lua_pushstring(L, "extensions"); openssl_sk_x509_extension_totable(L, exts); lua_rawset(L, -3); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } { X509_REQ_INFO* ri = csr->req_info; int i, c; EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); lua_newtable(L); c = X509_REQ_get_attr_count(csr); if (c > 0) { lua_newtable(L); for (i = 0; i < c ; i++) { X509_ATTRIBUTE *attr = X509_REQ_get_attr(csr, i); attr = X509_ATTRIBUTE_dup(attr); PUSH_OBJECT(attr, "openssl.x509_attribute"); lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "attributes"); } lua_newtable(L); openssl_push_asn1object(L, ri->pubkey->algor->algorithm); lua_setfield(L, -2, "algorithm"); AUXILIAR_SETOBJECT(L, pubkey , "openssl.evp_pkey", -1, "pubkey"); lua_setfield(L, -2, "pubkey"); lua_setfield(L, -2, "req_info"); } return 1; }
extList pki_x509req::getV3ext() { extList el; STACK_OF(X509_EXTENSION) *sk; sk = X509_REQ_get_extensions(request); el.setStack(sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); return el; }
/*** set extension of x509_req object @function extensions @tparam stack_of_x509_extension extensions @treturn boolean result true for success */ static LUA_FUNCTION(openssl_csr_extensions) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); if (lua_isnone(L, 2)) { STACK_OF(X509_EXTENSION) *sk = X509_REQ_get_extensions(csr); if (sk) { openssl_sk_x509_extension_totable(L, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); } else lua_pushnil(L); return 1; } else { STACK_OF(X509_EXTENSION) *sk = openssl_sk_x509_extension_fromtable(L, 2); int ret = X509_REQ_add_extensions(csr, sk); sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free); return openssl_pushresult(L, ret); } }
int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req) { X509_EXTENSION *ext; STACK_OF(X509_EXTENSION) *extlist = NULL; STACK_OF(CONF_VALUE) *nval; CONF_VALUE *val; int i; if(!(nval = CONF_get_section(conf, section))) return 0; for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) return 0; if(!extlist) extlist = sk_X509_EXTENSION_new_null(); sk_X509_EXTENSION_push(extlist, ext); } if(req) i = X509_REQ_add_extensions(req, extlist); else i = 1; sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); return i; }
static VALUE ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, VALUE reason, VALUE revtime, VALUE thisupd, VALUE nextupd, VALUE ext) { OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; OCSP_CERTID *id; int st, rsn; ASN1_TIME *ths, *nxt, *rev; int error, i, rstatus = 0; VALUE tmp; st = NUM2INT(status); rsn = NIL_P(status) ? 0 : NUM2INT(reason); if(!NIL_P(ext)) { /* All ary's members should be X509Extension */ Check_Type(ext, T_ARRAY); for (i = 0; i < RARRAY_LEN(ext); i++) OSSL_Check_Kind(RARRAY_AT(ext, i), cX509Ext); } error = 0; ths = nxt = rev = NULL; if(!NIL_P(revtime)) { tmp = rb_protect(rb_Integer, revtime, &rstatus); if(rstatus) goto err; rev = X509_gmtime_adj(NULL, NUM2INT(tmp)); } tmp = rb_protect(rb_Integer, thisupd, &rstatus); if(rstatus) goto err; ths = X509_gmtime_adj(NULL, NUM2INT(tmp)); tmp = rb_protect(rb_Integer, nextupd, &rstatus); if(rstatus) goto err; nxt = X509_gmtime_adj(NULL, NUM2INT(tmp)); GetOCSPBasicRes(self, bs); SafeGetOCSPCertId(cid, id); if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))) { error = 1; goto err; } if(!NIL_P(ext)) { X509_EXTENSION *x509ext; sk_X509_EXTENSION_pop_free(single->singleExtensions, X509_EXTENSION_free); single->singleExtensions = NULL; for(i = 0; i < RARRAY_LEN(ext); i++) { x509ext = DupX509ExtPtr(RARRAY_AT(ext, i)); if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)) { X509_EXTENSION_free(x509ext); error = 1; goto err; } X509_EXTENSION_free(x509ext); } } err: ASN1_TIME_free(ths); ASN1_TIME_free(nxt); ASN1_TIME_free(rev); if(error) ossl_raise(eOCSPError, NULL); if(rstatus) rb_jump_tag(rstatus); return self; }
int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { long l; EVP_PKEY *pkey; STACK_OF(X509_ATTRIBUTE) * sk; char mlch = ' '; int nmindent = 0; if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } if (nmflags == X509_FLAG_COMPAT) { nmindent = 16; } X509_REQ_INFO *ri = x->req_info; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 || BIO_write(bio, " Data:\n", 10) <= 0) { goto err; } } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_REQ_get_version(x); if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) { goto err; } } if (!(cflag & X509_FLAG_NO_SUBJECT)) { if (BIO_printf(bio, " Subject:%c", mlch) <= 0 || X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 || BIO_write(bio, "\n", 1) <= 0) { goto err; } } if (!(cflag & X509_FLAG_NO_PUBKEY)) { if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || BIO_puts(bio, "\n") <= 0) { goto err; } pkey = X509_REQ_get_pubkey(x); if (pkey == NULL) { BIO_printf(bio, "%12sUnable to load Public Key\n", ""); ERR_print_errors(bio); } else { EVP_PKEY_print_public(bio, pkey, 16, NULL); EVP_PKEY_free(pkey); } } if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) { goto err; } sk = x->req_info->attributes; if (sk_X509_ATTRIBUTE_num(sk) == 0) { if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) { goto err; } } else { size_t i; for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i); ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a); if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) { continue; } if (BIO_printf(bio, "%12s", "") <= 0) { goto err; } const int num_attrs = X509_ATTRIBUTE_count(a); const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj); if (obj_str_len <= 0) { if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) { goto err; } else { continue; } } int j; for (j = 0; j < num_attrs; j++) { const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j); const int type = at->type; ASN1_BIT_STRING *bs = at->value.asn1_string; int k; for (k = 25 - obj_str_len; k > 0; k--) { if (BIO_write(bio, " ", 1) != 1) { goto err; } } if (BIO_puts(bio, ":") <= 0) { goto err; } if (type == V_ASN1_PRINTABLESTRING || type == V_ASN1_UTF8STRING || type == V_ASN1_IA5STRING || type == V_ASN1_T61STRING) { if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) { goto err; } BIO_puts(bio, "\n"); } else { BIO_puts(bio, "unable to print attribute\n"); } } } } } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x); if (exts) { BIO_printf(bio, "%8sRequested Extensions:\n", ""); size_t i; for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); if (BIO_printf(bio, "%12s", "") <= 0) { goto err; } ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bio, obj); const int is_critical = X509_EXTENSION_get_critical(ex); if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) { goto err; } if (!X509V3_EXT_print(bio, ex, cflag, 16)) { BIO_printf(bio, "%16s", ""); ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex)); } if (BIO_write(bio, "\n", 1) <= 0) { goto err; } } sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } } if (!(cflag & X509_FLAG_NO_SIGDUMP) && !X509_signature_print(bio, x->sig_alg, x->signature)) { goto err; } return 1; err: OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); return 0; }
int tls_parse_ctos_status_request(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx, int *al) { PACKET responder_id_list, exts; /* Not defined if we get one of these in a client Certificate */ if (x != NULL) return 1; if (!PACKET_get_1(pkt, (unsigned int *)&s->ext.status_type)) { *al = SSL_AD_DECODE_ERROR; return 0; } if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) { /* * We don't know what to do with any other type so ignore it. */ s->ext.status_type = TLSEXT_STATUSTYPE_nothing; return 1; } if (!PACKET_get_length_prefixed_2 (pkt, &responder_id_list)) { *al = SSL_AD_DECODE_ERROR; return 0; } /* * We remove any OCSP_RESPIDs from a previous handshake * to prevent unbounded memory growth - CVE-2016-6304 */ sk_OCSP_RESPID_pop_free(s->ext.ocsp.ids, OCSP_RESPID_free); if (PACKET_remaining(&responder_id_list) > 0) { s->ext.ocsp.ids = sk_OCSP_RESPID_new_null(); if (s->ext.ocsp.ids == NULL) { *al = SSL_AD_INTERNAL_ERROR; return 0; } } else { s->ext.ocsp.ids = NULL; } while (PACKET_remaining(&responder_id_list) > 0) { OCSP_RESPID *id; PACKET responder_id; const unsigned char *id_data; if (!PACKET_get_length_prefixed_2(&responder_id_list, &responder_id) || PACKET_remaining(&responder_id) == 0) { *al = SSL_AD_DECODE_ERROR; return 0; } id_data = PACKET_data(&responder_id); /* TODO(size_t): Convert d2i_* to size_t */ id = d2i_OCSP_RESPID(NULL, &id_data, (int)PACKET_remaining(&responder_id)); if (id == NULL) { *al = SSL_AD_DECODE_ERROR; return 0; } if (id_data != PACKET_end(&responder_id)) { OCSP_RESPID_free(id); *al = SSL_AD_DECODE_ERROR; return 0; } if (!sk_OCSP_RESPID_push(s->ext.ocsp.ids, id)) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; return 0; } } /* Read in request_extensions */ if (!PACKET_as_length_prefixed_2(pkt, &exts)) { *al = SSL_AD_DECODE_ERROR; return 0; } if (PACKET_remaining(&exts) > 0) { const unsigned char *ext_data = PACKET_data(&exts); sk_X509_EXTENSION_pop_free(s->ext.ocsp.exts, X509_EXTENSION_free); s->ext.ocsp.exts = d2i_X509_EXTENSIONS(NULL, &ext_data, (int)PACKET_remaining(&exts)); if (s->ext.ocsp.exts == NULL || ext_data != PACKET_end(&exts)) { *al = SSL_AD_DECODE_ERROR; return 0; } } return 1; }
TokenError _backend_createRequest(const RegutilInfo *info, const char *hostname, const char *password, char **request, size_t *reqlen) { // OpenSSL seeds the PRNG automatically, see the manual page for RAND_add. if (!RAND_status()) { fprintf(stderr, BINNAME ": no random state!\n"); return TokenError_NoRandomState; } // Abort if there are no requests *request = NULL; if (!info->pkcs10) return TokenError_Unknown; // Create certificate requests bool ok = true; CertReq *reqs = NULL; STACK *x509reqs = sk_new_null(); for (const RegutilPKCS10 *pkcs10 = info->pkcs10; pkcs10 != NULL; pkcs10 = pkcs10->next) { RSA *rsa = NULL; EVP_PKEY *privkey = NULL; X509_NAME *subject = NULL; X509_REQ *x509req = NULL; STACK_OF(X509_EXTENSION) *exts = NULL; // Check the parameters. // Maximum key size in OpenSSL: // http://www.mail-archive.com/[email protected]/msg58229.html if (!pkcs10->subjectDN || pkcs10->keySize < 1024 || pkcs10->keySize > 16384) goto req_error; // Generate key pair // FIXME deprecated function // TODO use OPENSSL_NO_DEPRECATED rsa = RSA_generate_key(pkcs10->keySize, RSA_F4, NULL, NULL); if (!rsa) goto req_error; privkey = EVP_PKEY_new(); if (!privkey) goto req_error; EVP_PKEY_assign_RSA(privkey, rsa); // Subject name subject = certutil_parse_dn(pkcs10->subjectDN, pkcs10->includeFullDN); if (!subject) goto req_error; // Create request x509req = X509_REQ_new(); if (!x509req || !X509_REQ_set_version(x509req, 0) || !X509_REQ_set_subject_name(x509req, subject) || !X509_REQ_set_pubkey(x509req, privkey)) { // yes this is correct(!) certutil_updateErrorString(); goto req_error; } // Set attributes exts = sk_X509_EXTENSION_new_null(); if (!exts) goto req_error; X509_EXTENSION *ext = makeKeyUsageExt(pkcs10->keyUsage); if (!ext || !sk_X509_EXTENSION_push(exts, ext)) goto req_error; if (!X509_REQ_add_extensions(x509req, exts)) { certutil_updateErrorString(); goto req_error; } exts = NULL; // Add signature if (!X509_REQ_sign(x509req, privkey, EVP_sha1())) { certutil_updateErrorString(); goto req_error; } // Store in list CertReq *req = malloc(sizeof(CertReq)); req->pkcs10 = pkcs10; req->privkey = privkey; req->rsa = rsa; req->x509 = x509req; req->next = reqs; reqs = req; sk_push(x509reqs, (char*)x509req); continue; req_error: // Clean up and set error flag if (privkey) EVP_PKEY_free(privkey); else if (rsa) RSA_free(rsa); X509_NAME_free(subject); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); X509_REQ_free(x509req); ok = false; } TokenError error = TokenError_Unknown; if (ok) { // Determine filename from certificate name char *filename = certutil_makeFilename(X509_REQ_get_subject_name(reqs->x509)); // Build the certificate request request_wrap(x509reqs, request, reqlen); if (*request && filename) { // Create the key file in ~/cbt/name.p12 FILE *keyfile = platform_openLocked(filename, Platform_OpenCreate); if (!keyfile) { error = TokenError_CantCreateFile; } else { error = saveKeys(reqs, hostname, password, keyfile); if (!platform_closeLocked(keyfile) && !error) error = TokenError_CantCreateFile; } } if (filename) free(filename); if (error && *request) free(*request); } // Free reqs while (reqs) { RSA_free(reqs->rsa); // This free's privkey too X509_REQ_free(reqs->x509); CertReq *next = reqs->next; free(reqs); reqs = next; } sk_free(x509reqs); return error; }
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { unsigned long l; int i; const char *neg; X509_REQ_INFO *ri; EVP_PKEY *pkey; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(X509_EXTENSION) *exts; char mlch = ' '; int nmindent = 0; if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } if(nmflags == X509_FLAG_COMPAT) nmindent = 16; ri=x->req_info; if(!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err; if (BIO_write(bp," Data:\n",10) <= 0) goto err; } if(!(cflag & X509_FLAG_NO_VERSION)) { neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":""; l=0; for (i=0; i<ri->version->length; i++) { l<<=8; l+=ri->version->data[i]; } if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg, l) <= 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,ri->subject,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, ri->pubkey->algor->algorithm) <= 0) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; pkey=X509_REQ_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_ATTRIBUTES)) { /* may not be */ if(BIO_printf(bp,"%8sAttributes:\n","") <= 0) goto err; sk=x->req_info->attributes; if (sk_X509_ATTRIBUTE_num(sk) == 0) { if(BIO_printf(bp,"%12sa0:00\n","") <= 0) goto err; } else { for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) { ASN1_TYPE *at; X509_ATTRIBUTE *a; ASN1_BIT_STRING *bs=NULL; ASN1_TYPE *t; int j,type=0,count=1,ii=0; a=sk_X509_ATTRIBUTE_value(sk,i); if(X509_REQ_extension_nid(OBJ_obj2nid(a->object))) continue; if(BIO_printf(bp,"%12s","") <= 0) goto err; if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0) { if (a->single) { t=a->value.single; type=t->type; bs=t->value.bit_string; } else { ii=0; count=sk_ASN1_TYPE_num(a->value.set); get_next: at=sk_ASN1_TYPE_value(a->value.set,ii); type=at->type; bs=at->value.asn1_string; } } for (j=25-j; j>0; j--) if (BIO_write(bp," ",1) != 1) goto err; if (BIO_puts(bp,":") <= 0) goto err; if ( (type == V_ASN1_PRINTABLESTRING) || (type == V_ASN1_T61STRING) || (type == V_ASN1_IA5STRING)) { if (BIO_write(bp,(char *)bs->data,bs->length) != bs->length) goto err; BIO_puts(bp,"\n"); } else { BIO_puts(bp,"unable to print attribute\n"); } if (++ii < count) goto get_next; } } } if(!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if(exts) { BIO_printf(bp,"%8sRequested Extensions:\n",""); for (i=0; i<sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; int j; ex=sk_X509_EXTENSION_value(exts, i); if (BIO_printf(bp,"%12s","") <= 0) goto err; obj=X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp,obj); j=X509_EXTENSION_get_critical(ex); if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0) goto err; if(!X509V3_EXT_print(bp, ex, cflag, 16)) { BIO_printf(bp, "%16s", ""); M_ASN1_OCTET_STRING_print(bp,ex->value); } if (BIO_write(bp,"\n",1) <= 0) goto err; } sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } } if(!(cflag & X509_FLAG_NO_SIGDUMP)) { if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err; } return(1); err: X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB); return(0); }
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { long l; int i; EVP_PKEY *pkey; STACK_OF(X509_EXTENSION) *exts; char mlch = ' '; int nmindent = 0; if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } if (nmflags == X509_FLAG_COMPAT) nmindent = 16; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) goto err; if (BIO_write(bp, " Data:\n", 10) <= 0) goto err; } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_REQ_get_version(x); if (l >= 0 && l <= 2) { if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0) goto err; } else { if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 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_REQ_get_subject_name(x), nmindent, nmflags) < 0) goto err; if (BIO_write(bp, "\n", 1) <= 0) goto err; } if (!(cflag & X509_FLAG_NO_PUBKEY)) { X509_PUBKEY *xpkey; ASN1_OBJECT *koid; if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) goto err; if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) goto err; xpkey = X509_REQ_get_X509_PUBKEY(x); X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey); if (i2a_ASN1_OBJECT(bp, koid) <= 0) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; pkey = X509_REQ_get0_pubkey(x); if (pkey == NULL) { if (BIO_printf(bp, "%12sUnable to load Public Key\n", "") <= 0) goto err; ERR_print_errors(bp); } else { if (EVP_PKEY_print_public(bp, pkey, 16, NULL) <= 0) goto err; } } if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { /* may not be */ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) goto err; if (X509_REQ_get_attr_count(x) == 0) { if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) goto err; } else { for (i = 0; i < X509_REQ_get_attr_count(x); i++) { ASN1_TYPE *at; X509_ATTRIBUTE *a; ASN1_BIT_STRING *bs = NULL; ASN1_OBJECT *aobj; int j, type = 0, count = 1, ii = 0; a = X509_REQ_get_attr(x, i); aobj = X509_ATTRIBUTE_get0_object(a); if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) continue; if (BIO_printf(bp, "%12s", "") <= 0) goto err; if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) { ii = 0; count = X509_ATTRIBUTE_count(a); get_next: at = X509_ATTRIBUTE_get0_type(a, ii); type = at->type; bs = at->value.asn1_string; } for (j = 25 - j; j > 0; j--) if (BIO_write(bp, " ", 1) != 1) goto err; if (BIO_puts(bp, ":") <= 0) goto err; switch (type) { case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_NUMERICSTRING: case V_ASN1_UTF8STRING: case V_ASN1_IA5STRING: if (BIO_write(bp, (char *)bs->data, bs->length) != bs->length) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; break; default: if (BIO_puts(bp, "unable to print attribute\n") <= 0) goto err; break; } if (++ii < count) goto get_next; } } } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if (exts) { if (BIO_printf(bp, "%8sRequested Extensions:\n", "") <= 0) goto err; for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; int critical; ex = sk_X509_EXTENSION_value(exts, i); if (BIO_printf(bp, "%12s", "") <= 0) goto err; obj = X509_EXTENSION_get_object(ex); if (i2a_ASN1_OBJECT(bp, obj) <= 0) goto err; critical = X509_EXTENSION_get_critical(ex); if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0) goto err; if (!X509V3_EXT_print(bp, ex, cflag, 16)) { if (BIO_printf(bp, "%16s", "") <= 0 || ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)) <= 0) goto err; } if (BIO_write(bp, "\n", 1) <= 0) goto err; } sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } } if (!(cflag & X509_FLAG_NO_SIGDUMP)) { const X509_ALGOR *sig_alg; const ASN1_BIT_STRING *sig; X509_REQ_get0_signature(x, &sig, &sig_alg); if (!X509_signature_print(bp, sig_alg, sig)) goto err; } return 1; err: X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); return 0; }
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) { unsigned short type; unsigned short size; unsigned short len; unsigned char *data = *p; int renegotiate_seen = 0; s->servername_done = 0; s->tlsext_status_type = -1; if (data >= (d+n-2)) goto ri_check; n2s(data,len); if (data > (d+n-len)) goto ri_check; while (data <= (d+n-4)) { n2s(data,type); n2s(data,size); if (data+size > (d+n)) goto ri_check; if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); /* The servername extension is treated as follows: - Only the hostname type is supported with a maximum length of 255. - The servername is rejected if too long or if it contains zeros, in which case an fatal alert is generated. - The servername field is maintained together with the session cache. - When a session is resumed, the servername call back invoked in order to allow the application to position itself to the right context. - The servername is acknowledged if it is new for a session or when it is identical to a previously used for the same session. Applications can control the behaviour. They can at any time set a 'desirable' servername for a new SSL object. This can be the case for example with HTTPS when a Host: header field is received and a renegotiation is requested. In this case, a possible servername presented in the new client hello is only acknowledged if it matches the value of the Host: field. - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION if they provide for changing an explicit servername context for the session, i.e. when the session has been established with a servername extension. - On session reconnect, the servername extension may be absent. */ if (type == TLSEXT_TYPE_server_name) { unsigned char *sdata; int servname_type; int dsize; if (size < 2) { *al = SSL_AD_DECODE_ERROR; return 0; } n2s(data,dsize); size -= 2; if (dsize > size ) { *al = SSL_AD_DECODE_ERROR; return 0; } sdata = data; while (dsize > 3) { servname_type = *(sdata++); n2s(sdata,len); dsize -= 3; if (len > dsize) { *al = SSL_AD_DECODE_ERROR; return 0; } if (s->servername_done == 0) switch (servname_type) { case TLSEXT_NAMETYPE_host_name: if (!s->hit) { if(s->session->tlsext_hostname) { *al = SSL_AD_DECODE_ERROR; return 0; } if (len > TLSEXT_MAXLEN_host_name) { *al = TLS1_AD_UNRECOGNIZED_NAME; return 0; } if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL) { *al = TLS1_AD_INTERNAL_ERROR; return 0; } memcpy(s->session->tlsext_hostname, sdata, len); s->session->tlsext_hostname[len]='\0'; if (strlen(s->session->tlsext_hostname) != len) { OPENSSL_free(s->session->tlsext_hostname); s->session->tlsext_hostname = NULL; *al = TLS1_AD_UNRECOGNIZED_NAME; return 0; } s->servername_done = 1; } else s->servername_done = s->session->tlsext_hostname && strlen(s->session->tlsext_hostname) == len && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; break; default: break; } dsize -= len; } if (dsize != 0) { *al = SSL_AD_DECODE_ERROR; return 0; } } else if (type == TLSEXT_TYPE_renegotiate) { if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) return 0; renegotiate_seen = 1; } else if (type == TLSEXT_TYPE_status_request && s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb) { if (size < 5) { *al = SSL_AD_DECODE_ERROR; return 0; } s->tlsext_status_type = *data++; size--; if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { const unsigned char *sdata; int dsize; /* Read in responder_id_list */ n2s(data,dsize); size -= 2; if (dsize > size ) { *al = SSL_AD_DECODE_ERROR; return 0; } while (dsize > 0) { OCSP_RESPID *id; int idsize; if (dsize < 4) { *al = SSL_AD_DECODE_ERROR; return 0; } n2s(data, idsize); dsize -= 2 + idsize; size -= 2 + idsize; if (dsize < 0) { *al = SSL_AD_DECODE_ERROR; return 0; } sdata = data; data += idsize; id = d2i_OCSP_RESPID(NULL, &sdata, idsize); if (!id) { *al = SSL_AD_DECODE_ERROR; return 0; } if (data != sdata) { OCSP_RESPID_free(id); *al = SSL_AD_DECODE_ERROR; return 0; } if (!s->tlsext_ocsp_ids && !(s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null())) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; return 0; } if (!sk_OCSP_RESPID_push( s->tlsext_ocsp_ids, id)) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; return 0; } } /* Read in request_extensions */ if (size < 2) { *al = SSL_AD_DECODE_ERROR; return 0; } n2s(data,dsize); size -= 2; if (dsize != size) { *al = SSL_AD_DECODE_ERROR; return 0; } sdata = data; if (dsize > 0) { if (s->tlsext_ocsp_exts) { sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); } s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, &sdata, dsize); if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) { *al = SSL_AD_DECODE_ERROR; return 0; } } } /* We don't know what to do with any other type * so ignore it. */ else s->tlsext_status_type = -1; } /* session ticket processed earlier */ data+=size; } *p = data; ri_check: /* Need RI if renegotiating */ if (!renegotiate_seen && s->new_session && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { *al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); return 0; } return 1; }
/*** parse x509_req object as table @function parse @tparam[opt=true] shortname default will use short object name @treturn table result */ static LUA_FUNCTION(openssl_csr_parse) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); X509_NAME *subject = X509_REQ_get_subject_name(csr); STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(csr); lua_newtable(L); { const ASN1_BIT_STRING *sig = NULL; const X509_ALGOR *alg = NULL; X509_REQ_get0_signature(csr, &sig, &alg); openssl_push_asn1(L, sig, V_ASN1_BIT_STRING); lua_setfield(L, -2, "signature"); alg = X509_ALGOR_dup((X509_ALGOR *)alg); PUSH_OBJECT(alg, "openssl.x509_algor"); lua_setfield(L, -2, "sig_alg"); } lua_newtable(L); AUXILIAR_SET(L, -1, "version", X509_REQ_get_version(csr), integer); openssl_push_xname_asobject(L, subject); lua_setfield(L, -2, "subject"); if (exts) { lua_pushstring(L, "extensions"); openssl_sk_x509_extension_totable(L, exts); lua_rawset(L, -3); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } { X509_PUBKEY *xpub = X509_REQ_get_X509_PUBKEY(csr); ASN1_OBJECT *oalg = NULL; int c; EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); lua_newtable(L); c = X509_REQ_get_attr_count(csr); if (c > 0) { int i; lua_newtable(L); for (i = 0; i < c ; i++) { X509_ATTRIBUTE *attr = X509_REQ_get_attr(csr, i); attr = X509_ATTRIBUTE_dup(attr); PUSH_OBJECT(attr, "openssl.x509_attribute"); lua_rawseti(L, -2, i + 1); } lua_setfield(L, -2, "attributes"); } lua_newtable(L); if (X509_PUBKEY_get0_param(&oalg, NULL, NULL, NULL, xpub)) { openssl_push_asn1object(L, oalg); lua_setfield(L, -2, "algorithm"); } AUXILIAR_SETOBJECT(L, pubkey, "openssl.evp_pkey", -1, "pubkey"); lua_setfield(L, -2, "pubkey"); lua_setfield(L, -2, "req_info"); } return 1; }
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag) { long l; int i; X509_REQ_INFO *ri; EVP_PKEY *pkey; STACK_OF(X509_ATTRIBUTE) *sk; STACK_OF(X509_EXTENSION) *exts; char mlch = ' '; int nmindent = 0; if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { mlch = '\n'; nmindent = 12; } if (nmflags == X509_FLAG_COMPAT) nmindent = 16; ri = x->req_info; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) goto err; if (BIO_write(bp, " Data:\n", 10) <= 0) goto err; } if (!(cflag & X509_FLAG_NO_VERSION)) { l = X509_REQ_get_version(x); if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 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, ri->subject, 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, ri->pubkey->algor->algorithm) <= 0) goto err; if (BIO_puts(bp, "\n") <= 0) goto err; pkey = X509_REQ_get_pubkey(x); if (pkey == NULL) { BIO_printf(bp, "%12sUnable to load Public Key\n", ""); ERR_print_errors(bp); } else { EVP_PKEY_print_public(bp, pkey, 16, NULL); EVP_PKEY_free(pkey); } } if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { /* may not be */ if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) goto err; sk = x->req_info->attributes; if (sk_X509_ATTRIBUTE_num(sk) == 0) { if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) goto err; } else { for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { ASN1_TYPE *at; X509_ATTRIBUTE *a; ASN1_BIT_STRING *bs = NULL; ASN1_OBJECT *aobj; int j, type = 0, count = 1, ii = 0; a = sk_X509_ATTRIBUTE_value(sk, i); aobj = X509_ATTRIBUTE_get0_object(a); if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) continue; if (BIO_printf(bp, "%12s", "") <= 0) goto err; if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) { ii = 0; count = X509_ATTRIBUTE_count(a); get_next: at = X509_ATTRIBUTE_get0_type(a, ii); type = at->type; bs = at->value.asn1_string; } for (j = 25 - j; j > 0; j--) if (BIO_write(bp, " ", 1) != 1) goto err; if (BIO_puts(bp, ":") <= 0) goto err; if ((type == V_ASN1_PRINTABLESTRING) || (type == V_ASN1_T61STRING) || (type == V_ASN1_IA5STRING)) { if (BIO_write(bp, (char *)bs->data, bs->length) != bs->length) goto err; BIO_puts(bp, "\n"); } else { BIO_puts(bp, "unable to print attribute\n"); } if (++ii < count) goto get_next; } } } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { exts = X509_REQ_get_extensions(x); if (exts) { BIO_printf(bp, "%8sRequested Extensions:\n", ""); for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { ASN1_OBJECT *obj; X509_EXTENSION *ex; int j; ex = sk_X509_EXTENSION_value(exts, i); if (BIO_printf(bp, "%12s", "") <= 0) goto err; obj = X509_EXTENSION_get_object(ex); i2a_ASN1_OBJECT(bp, obj); j = X509_EXTENSION_get_critical(ex); if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) goto err; if (!X509V3_EXT_print(bp, ex, cflag, 16)) { BIO_printf(bp, "%16s", ""); ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex)); } if (BIO_write(bp, "\n", 1) <= 0) goto err; } sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); } } if (!(cflag & X509_FLAG_NO_SIGDUMP)) { if (!X509_signature_print(bp, x->sig_alg, x->signature)) goto err; } return (1); err: X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); return (0); }
int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days) { X509_REQ *x; EVP_PKEY *pk; RSA *rsa; X509_NAME *name=NULL; STACK_OF(X509_EXTENSION) *exts = NULL; if ((pk=EVP_PKEY_new()) == NULL) goto err; if ((x=X509_REQ_new()) == NULL) goto err; rsa=RSA_generate_key(bits,RSA_F4,callback,NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) goto err; rsa=NULL; X509_REQ_set_pubkey(x,pk); name=X509_REQ_get_subject_name(x); /* This function creates and adds the entry, working out the * correct string type and performing checks on its length. * Normally we'd check the return value for errors... */ X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, "UK", -1, -1, 0); X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, "OpenSSL Group", -1, -1, 0); #ifdef REQUEST_EXTENSIONS /* Certificate requests can contain extensions, which can be used * to indicate the extensions the requestor would like added to * their certificate. CAs might ignore them however or even choke * if they are present. */ /* For request extensions they are all packed in a single attribute. * We save them in a STACK and add them all at once later... */ exts = sk_X509_EXTENSION_new_null(); /* Standard extenions */ add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment"); /* This is a typical use for request extensions: requesting a value for * subject alternative name. */ add_ext(exts, NID_subject_alt_name, "email:[email protected]"); /* Some Netscape specific extensions */ add_ext(exts, NID_netscape_cert_type, "client,email"); #ifdef CUSTOM_EXT /* Maybe even add our own extension based on existing */ { int nid; nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension"); X509V3_EXT_add_alias(nid, NID_netscape_comment); add_ext(x, nid, "example comment alias"); } #endif /* Now we've created the extensions we add them to the request */ X509_REQ_add_extensions(x, exts); sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); #endif if (!X509_REQ_sign(x,pk,EVP_md5())) goto err; *req=x; *pkeyp=pk; return(1); err: return(0); }
int32_t HttpsGenCertReq( HttpsCertReqInfo_t *pCertReqInfo, unsigned char *pPrivbuf, unsigned char *pCertbuf, HttpsCertReqParams_t *pParams ) { EVP_PKEY *pkey = NULL; HX509Req_t *preq = NULL; #ifdef OPENSSL_9_7 const EVP_MD *pDigest; #else EVP_MD *pDigest = NULL; #endif /*OPENSSL_9_7*/ int32_t iRetVal; unsigned char aSubAltName[HTTPS_PARAMS_SUB_NAME_LEN]; bool bFlag = FALSE; STACK_OF(X509_EXTENSION) *skExtensions = NULL; X509_EXTENSION *pSubExt = NULL; unsigned char ucCT; int32_t uileng; /** * Input Validations... */ if (pCertReqInfo == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid parameters\n"); return OF_FAILURE; } /** * Allocate space for the public-private key pair.. */ if ((pkey = EVP_PKEY_new()) == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: MemAlloc failure\n"); return OF_FAILURE; } /** * Generate a public-private key pair.. */ switch (pCertReqInfo->usCertType) { case RSA_MD5: case RSA_SHA1: if ((pCertReqInfo->cr_params.rsa_params.usNumBits < MIN_KEY_LENGTH)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq : Invalid RSA parameters\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } if (!EVP_PKEY_assign_RSA(pkey, RSA_generate_key(pCertReqInfo->cr_params.rsa_params.usNumBits, 0x10001, NULL, NULL))) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq: EVP_PKEY assign failed\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } ucCT='r'; if (pCertReqInfo->usCertType == RSA_MD5) { pDigest = (EVP_MD *) EVP_md5(); } else { pDigest = (EVP_MD *) EVP_sha1(); } break; default: Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid certificate type\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Prepare the Certificate Request.. */ if ((preq = HttpsCertReqNew()) == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_req_new failed\n"); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Version Number.. */ if (!ASN1_INTEGER_set(preq->req_info->version, 0L)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: ASN1_INTEGER_set failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Subject Name...Filled with two RDNs... */ /** * RDN # 1 : Country Name... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->ucCn, NID_countryName, 2, 2)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } #ifdef OPENSSL_9_7 if (NID_postalCode == 0) { NID_postalCode = OBJ_create("2.5.4.17", "2.5.4.17", "postal code attribute"); } #endif /** * RDN #New::2: Postal code... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aPostalCode, NID_postalCode, 0, 10)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #3: State.. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aState, NID_stateOrProvinceName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #New::4: Locality Name... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aCity, NID_localityName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #5 : Organization .. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aOrg, NID_organizationName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #6 : Department .. */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->aDept, NID_organizationalUnitName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * RDN #7 : Common Name (Subject)... */ if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL, NULL, (char *) pParams->ucSub, NID_commonName, 0, 50)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Httpsadd_DN_object failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } of_memset( aSubAltName, 0, HTTPS_PARAMS_SUB_NAME_LEN); if (strlen((char *) pParams->aIpAddr)) { of_strcat((char *) aSubAltName, "IP:"); of_strcat((char *) aSubAltName, (char *) pParams->aIpAddr); bFlag = TRUE; } if (strlen((char *) pParams->aEmailId)) { if (bFlag) { of_strcat((char *) aSubAltName, ",email:"); } else { of_strcat((char *) aSubAltName, "email:"); } of_strcat((char *) aSubAltName, (char *) pParams->aEmailId); bFlag = TRUE; } if (strlen((char *) pParams->aDomain)) { if (bFlag) { of_strcat((char *) aSubAltName, ",DNS:"); } else { of_strcat((char *) aSubAltName, "DNS:"); } of_strcat((char *) aSubAltName, (char *) pParams->aDomain); bFlag = TRUE; } /** * Adding subject alt name extension to the request. */ if ( of_strlen((char *) aSubAltName)) { skExtensions = sk_X509_EXTENSION_new_null(); if (skExtensions == NULL) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: sk_X509_EXTENSION_new_null failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } pSubExt = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name, (char *) aSubAltName); if (pSubExt) { sk_X509_EXTENSION_push(skExtensions, pSubExt); } iRetVal = X509_REQ_add_extensions(preq, skExtensions); if (iRetVal == 0) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_add_extensions failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } sk_X509_EXTENSION_pop_free(skExtensions, X509_EXTENSION_free); } /* strlen sub alt */ /** * Set the public key.. */ if (!X509_REQ_set_pubkey(preq, pkey)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_sign failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Sign the CertReq Info.. */ if (!X509_REQ_sign(preq, pkey, pDigest)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: X509_REQ_sign failed\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Write the Private Key into the file... */ if (HttpsWritetoFile(pPrivbuf, HTTPS_PRIV_KEY, pkey, ucCT, pParams->aIdName)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: HttpsWritetoFile failed #1\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } /** * Write the Certificate Request into the file... */ if (HttpsWritetoFile(pCertbuf, HTTPS_CERT_REQ, preq, ucCT, pParams->aIdName)) { Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: HttpsWritetoFile failed #2\n"); HttpsDeleteCerts(pParams->aIdName, 's'); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } uileng=strlen((char *) pCertbuf); if (uileng > 2047) { Trace(HTTPS_ID, TRACE_SEVERE, "pCertbuf length exceeds 2k\n"); HttpsDeleteCerts(pParams->aIdName, 's'); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_FAILURE; } Trace(HTTPS_ID, TRACE_INFO, "Generation of Certificate Request done\n"); HttpsCertReqFree(preq); EVP_PKEY_free(pkey); return OF_SUCCESS; } /* HttpsGenCertReq() */
// reads the request req_filename and creates a modified creq_filename with the commitment extension added void writeCommitmentCSR(BIGNUM *commitment_c, char *privkey_filename, char *req_filename, char *creq_filename) { FILE *fp; /* read in the request */ X509_REQ *req; if (!(fp = fopen(req_filename, "r"))) critical_error("Error reading request file"); if (!(req = PEM_read_X509_REQ(fp, NULL, NULL, NULL))) critical_error("Error reading request in file"); fclose(fp); /* read in the private key */ EVP_PKEY *pkey; if (!(fp = fopen(privkey_filename, "r"))) critical_error("Error reading private key file"); if (!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL))) critical_error("Error reading private key in file"); fclose(fp); /* create the new request */ X509_REQ *creq; if (!(creq = X509_REQ_new())) critical_error("Failed to create X509_REQ object"); X509_REQ_set_pubkey(creq, pkey); // gets subj from initial requests and adds it to new one X509_NAME *subj = X509_REQ_get_subject_name(req); if (X509_REQ_set_subject_name(creq, subj) != 1) critical_error("Error adding subject to request"); // enable the commitment extension handling (retrieve/print as string) int nid = _commitmentExt_start(); // get extensions stack of original request STACK_OF(X509_EXTENSION) *extlist = X509_REQ_get_extensions(req); // if no extensions, create new stack if (extlist==NULL) { extlist = sk_X509_EXTENSION_new_null(); } else { // else check that the extension isn't already there (error!) X509_EXTENSION *tmp = (X509_EXTENSION*) X509V3_get_d2i(extlist, nid, NULL, NULL); if (tmp!=NULL) critical_error("Aborting process: CSR already contains commitment extension!\n"); } // create commitment extension storing C value as a hex string X509_EXTENSION *exCommitment = (X509_EXTENSION*) X509V3_EXT_conf_nid(NULL, NULL, nid, BN_bn2hex(commitment_c)); if (!exCommitment) critical_error("error creating commitment extension"); // push commitment extension into stack sk_X509_EXTENSION_push(extlist, exCommitment); // assign extensions to the new request if (!X509_REQ_add_extensions(creq, extlist)) critical_error("Error adding extensions to the request"); sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); ///////////////////////////////////////////////////////////////////// /* pick the correct digest and sign the new request */ EVP_MD *digest; if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) digest = (EVP_MD*) EVP_dss1(); else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) digest = (EVP_MD*) EVP_sha1(); else critical_error("Error checking public key for a valid digest"); if (!(X509_REQ_sign(creq, pkey, digest))) critical_error("Error signing request"); /* write the modified request */ if (!(fp = fopen(creq_filename, "w"))) critical_error("Error writing to request file"); if (PEM_write_X509_REQ(fp, creq) != 1) critical_error("Error while writing request"); fclose(fp); // cleanup _commitmentExt_end(); EVP_PKEY_free(pkey); X509_REQ_free(req); X509_REQ_free(creq); }