static LUA_FUNCTION(openssl_csr_read) { BIO * in = load_bio_object(L, 1); int fmt = luaL_checkoption(L, 2, "auto", format); X509_REQ * csr = NULL; if (fmt == FORMAT_AUTO) { fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM; } if (fmt == FORMAT_PEM) { csr = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_reset(in); }else if (fmt == FORMAT_DER) { csr = d2i_X509_REQ_bio(in, NULL); BIO_reset(in); } BIO_free(in); if (csr) { PUSH_OBJECT(csr, "openssl.x509_req"); return 1; } return openssl_pushresult(L, 0); }
int main(int argc, char **argv) { X509_REQ *pkcs10 = NULL; BIO *bio = NULL; has_t *p10 = NULL; char *json = NULL; size_t l; openssl_init(); if ((bio = BIO_new(BIO_s_file())) == NULL) { return -1; } if(argc < 2) { BIO_set_fp(bio, stdin, BIO_NOCLOSE); } else { BIO_read_filename(bio, argv[1]); } /* Format DER */ if((pkcs10 = d2i_X509_REQ_bio(bio, NULL)) == NULL) { ERR_clear_error(); /* Format PEM */ pkcs10 = PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL); } if(!pkcs10) { fprintf(stderr, "Error loading certificate\n"); return -1; } if((p10 = has_pkcs10_new(pkcs10)) == NULL) { fprintf(stderr, "Error converting certificate\n"); return -1; } if(has_json_serialize(p10, &json, &l, HAS_JSON_SERIALIZE_PRETTY) == 0) { printf("%s\n", json); free(json); } else { fprintf(stderr, "Error serializing certificate\n"); return -1; } has_free(p10); X509_REQ_free(pkcs10); BIO_free(bio); openssl_cleanup(); return 0; }
Handle<CertificationRequest> Provider_System::getCSRFromURI(Handle<std::string> uri, Handle<std::string> format){ LOGGER_FN(); try{ BIO *bioFile = NULL; X509_REQ *hreq = NULL; LOGGER_OPENSSL(BIO_new); bioFile = BIO_new(BIO_s_file()); LOGGER_OPENSSL(BIO_read_filename); if (BIO_read_filename(bioFile, uri->c_str()) > 0){ LOGGER_OPENSSL(BIO_seek); BIO_seek(bioFile, 0); if (strcmp(format->c_str(), "PEM") == 0){ LOGGER_OPENSSL(PEM_read_bio_X509_REQ); hreq = PEM_read_bio_X509_REQ(bioFile, NULL, NULL, NULL); } else if (strcmp(format->c_str(), "DER") == 0){ LOGGER_OPENSSL(d2i_X509_REQ_bio); hreq = d2i_X509_REQ_bio(bioFile, NULL); } else{ THROW_EXCEPTION(0, Provider_System, NULL, "Unsupported format. Only PEM | DER"); } } LOGGER_OPENSSL(BIO_free); BIO_free(bioFile); if (!hreq){ THROW_EXCEPTION(0, Provider_System, NULL, "Unable decode csr from PEM/DER"); } else{ return new CertificationRequest(hreq); } } catch (Handle<Exception> e){ THROW_EXCEPTION(0, Provider_System, e, "getCSRFromURI"); } }
/* * read requestor data * * for version 2 requests, the requestor and the SCEP client can be different * and the request does not need to be a PKCS#10 */ static int read_requestorstuff(scep_t *scep, int type, char *filename) { BIO *bio; NETSCAPE_SPKI *spki = NULL; X509_REQ *req = NULL; bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, filename) < 0) { BIO_printf(bio_err, "%s:%d: cannot read request file '%s'\n", __FILE__, __LINE__, filename); goto err; } switch (type) { case 0: scep->requestorreq = d2i_X509_REQ_bio(bio, &req); if (scep->requestorreq == NULL) { BIO_printf(bio_err, "%s:%d: cannot decode X509_REQ\n", __FILE__, __LINE__); goto err; } scep->requestorpubkey = X509_REQ_get_pubkey(scep->requestorreq); break; case 1: scep->requestorspki = d2i_NETSCAPE_SPKI_bio(bio, &spki); if (scep->requestorspki == NULL) { BIO_printf(bio_err, "%s:%d: cannot decode SPKI\n", __FILE__, __LINE__); goto err; } scep->requestorpubkey = NETSCAPE_SPKI_get_pubkey(scep->requestorspki); break; default: goto err; } return 0; err: ERR_print_errors(bio_err); return -1; }
/* * We use a simple lookup table to simulate manual enrollment * of certs by the CA. This is the case where an operator * needs to review each cert request and approve it (e.g. * auto-enrollment is off). * * Return 1 if a match was found and the enrollment operation * should proceed. Return 0 if no match was found, in which * case we'll add the public key from the cert request into * our lookup table so it can be correlated later. * * Windows: Rewriting to forgo the use of search.h API * lookup table will be implemented as a basic linked list */ static int lookup_pkcs10_request(unsigned char *pkcs10, int p10_len) { X509_REQ *req = NULL; BIO *in = NULL; BIO *out = NULL; BIO *b64; EVP_PKEY *pkey = NULL; BUF_MEM *bptr; int rv; LOOKUP_ENTRY *l; LOOKUP_ENTRY *n; /* * Decode the request into an X509_REQ structure */ b64 = BIO_new(BIO_f_base64()); in = BIO_new_mem_buf(pkcs10, p10_len); in = BIO_push(b64, in); if ((req = d2i_X509_REQ_bio(in, NULL)) == NULL) { /* Unable to parse the request, just let this fall through * and the enrollment will fail */ rv = 1; goto DONE; } /* * Get the public key from the request, this will be our index into * the lookup table. Frankly, I'm not sure how a real CA * would do this lookup. But this should be good enough for * testing the retry-after logic. */ pkey = X509_PUBKEY_get(req->req_info->pubkey); if (!pkey) { rv = 1; goto DONE; } out = BIO_new(BIO_s_mem()); PEM_write_bio_PUBKEY(out, pkey); BIO_get_mem_ptr(out, &bptr); /* * see if we can find a match for this public key */ n = malloc(sizeof(LOOKUP_ENTRY)); n->data = malloc(bptr->length); n->length = bptr->length; memcpy(n->data, bptr->data, n->length); n->next = NULL; l = search_list(lookup_root, n); if (l) { /* We have a match, allow the enrollment */ rv = 1; lookup_root = delete_lookup_entry(lookup_root, n); printf("\nRemoving key from lookup table:\n"); dumpbin((char*)n->data, n->length); free(n->data); free(n); } else { /* Not a match, add it to the list and return */ if (lookup_root == NULL) { /* * Initialize the list */ lookup_root = n; } else { add_entry(lookup_root, n); } rv = 0; printf("\nAdding key to lookup table:\n"); dumpbin((char*)n->data, n->length); } DONE: if (out) BIO_free_all(out); if (in) BIO_free_all(in); if (req) X509_REQ_free(req); if (pkey) EVP_PKEY_free(pkey); return (rv); }
static scepitem_t *readitem(char *transid) { scepitem_t *si; BIO *bio; char filename[1024]; char oneline[1024]; X509_NAME *name; /* allocate a new structure */ si = (scepitem_t *)malloc(sizeof(scepitem_t)); /* first create a copy of the transid */ si->transid = strdup(transid); /* make sure that it has the right length */ si->transid[32] = '\0'; /* find the appropriate file: request or certificate */ switch (itemselect) { case SELECT_PENDING: case SELECT_REJECTED: si->type = ITEM_TYPE_REQ; break; case SELECT_GRANTED: case SELECT_REVOKED: si->type = ITEM_TYPE_CERT; break; } /* create the filename for the item */ snprintf(filename, sizeof(filename), "%s/%s/%s.der", OPENSCEPDIR, selectname[itemselect], si->transid); if (debug) fprintf(stderr, "%s:%d: trying file '%s'\n", __FILE__, __LINE__, filename); /* open the file and read the contents */ bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, filename) < 0) { fprintf(stderr, "%s:%d: cannot open file %s\n", __FILE__, __LINE__, filename); return NULL; } switch (si->type) { case ITEM_TYPE_REQ: si->data.req = d2i_X509_REQ_bio(bio, NULL); break; case ITEM_TYPE_CERT: si->data.x509 = d2i_X509_bio(bio, NULL); break; } if (si->data.any == NULL) { fprintf(stderr, "%s:%d: cannot decode item, trans id %s\n", __FILE__, __LINE__, si->transid); ERR_print_errors(bio_err); return NULL; } else { if (debug) BIO_printf(bio_err, "%s:%d: got new item\n", __FILE__, __LINE__); } /* extract key information from request or certificate */ switch (sortorder) { case SORT_TRANSID: si->key = strdup(si->transid); break; case SORT_NAME: name = (si->type == ITEM_TYPE_REQ) ? X509_REQ_get_subject_name(si->data.req) : X509_get_subject_name(si->data.x509); X509_NAME_oneline(name, oneline, sizeof(oneline)); si->key = strdup(oneline); break; case SORT_NOTBEFORE: si->key = asn1_time_to_string(X509_get_notBefore( si->data.x509)); break; case SORT_NOTAFTER: si->key = asn1_time_to_string(X509_get_notAfter(si->data.x509)); break; case SORT_SERIAL: si->key = X509_get_serialNumber(si->data.x509); break; } /* return the completely filled in item */ return si; }
static void sign_req (int fd, void *unused) { char thefile[80], cmd_buf[300], p7[3000]; int i, num; unsigned char *data, *asn1; int32_t msglen; BIO *bio = NULL; FILE *fp; struct stat blah; X509_REQ *req = NULL; EVP_ENCODE_CTX ctx; if (recv(fd, (char *)&msglen, sizeof(int32_t), MSG_WAITALL) < sizeof(int32_t)) { return; } msglen = ntohl(msglen); if (msglen > 3000) { return; } if ((data = (unsigned char *)malloc(msglen)) == NULL) { return; } if ((asn1 = (unsigned char *)malloc(msglen)) == NULL) { free(data); return; } if (recv(fd, (char *)data, msglen, MSG_WAITALL) < msglen) { free(data); return; } EVP_DecodeInit(&ctx); EVP_DecodeUpdate(&ctx, asn1, &i, data, msglen); num = i; EVP_DecodeFinal(&ctx, &(asn1[i]), &i); num += i; free(data); if ((bio = BIO_new_mem_buf(asn1, num)) == NULL) { free(asn1); goto no_cert; } if ((req = d2i_X509_REQ_bio(bio, NULL)) == NULL) { free(asn1); goto no_cert; } free(asn1); BIO_free(bio); bio = NULL; unique++; memset(thefile, 0, sizeof(thefile)); snprintf(thefile, sizeof(thefile), "%dreq.pem", unique); if ((fp = fopen(thefile, "w+")) == NULL) { goto no_cert; } if ((bio = BIO_new(BIO_s_file())) == NULL) { fprintf(stderr, "unable to create bio for CSR\n"); goto no_cert; } BIO_set_fp(bio, fp, BIO_NOCLOSE); PEM_write_bio_X509_REQ(bio, req); (void)BIO_flush(bio); BIO_free(bio); bio = NULL; fclose(fp); snprintf(cmd_buf, sizeof(cmd_buf), "openssl ca " "-policy policy_anything -batch -notext " "-config ./conf/openssl.cnf " "-out %dcert.pem -in %dreq.pem", unique, unique); system(cmd_buf); unlink(thefile); snprintf(thefile, sizeof(thefile), "%dcert.pem", unique); if ((stat(thefile, &blah) < 0) || (blah.st_size < 1)) { goto no_cert; } snprintf(cmd_buf, sizeof(cmd_buf), "openssl crl2pkcs7 " "-certfile %dcert.pem -outform DER -out %dder.p7 -nocrl", unique, unique); system(cmd_buf); unlink(thefile); snprintf(thefile, sizeof(thefile), "%dder.p7", unique); if (stat(thefile, &blah) < 0) { goto no_cert; } i = blah.st_size; printf("DER-encoded P7 is %d bytes\n", i); if ((data = (unsigned char *)malloc(blah.st_size*2)) == NULL) { goto no_cert; } if ((fp = fopen(thefile, "r")) == NULL) { free(data); goto no_cert; } if (fread(p7, 1, sizeof(p7), fp) < blah.st_size) { free(data); goto no_cert; } fclose(fp); unlink(thefile); i = 0; EVP_EncodeInit(&ctx); EVP_EncodeUpdate(&ctx, data, &i, (unsigned char *)p7, blah.st_size); num = i; EVP_EncodeFinal(&ctx, (unsigned char *)&(data[i]), &i); num += i; printf("PEM-encoded P7 is %d bytes\n", num); msglen = num; msglen = htonl(msglen); send(fd, (char *)&msglen, sizeof(int32_t), 0); send(fd, (char *)data, num, 0); free(data); no_cert: BIO_free(bio); srv_rem_input(srvctx, fd); close(fd); return; }
inline certificate_request certificate_request::from_der(bio::bio_ptr bio) { return take_ownership(d2i_X509_REQ_bio(bio.raw(), NULL)); }
Handle<PkiItem> Provider_System::objectToPKIItem(Handle<std::string> uri){ LOGGER_FN(); Handle<PkiItem> item; Handle<Bio> in = new Bio(BIO_TYPE_FILE, uri->c_str(), "rb"); try{ item = new PkiItem(); X509_REQ *xreq = NULL; X509 *xcert = NULL; X509_CRL *xcrl = NULL; Handle<Certificate> hcert = NULL; Handle<CRL> hcrl = NULL; std::string listCertStore[] = { "MY", "OTHERS", "TRUST", "CRL" }; std::string strTrust = (uri->substr(0, (uri->find_last_of(CROSSPLATFORM_SLASH)))); strTrust = strTrust.substr(strTrust.find_last_of(CROSSPLATFORM_SLASH) + 1, strTrust.length()); bool trueTrust = false; for (int i = 0, c = sizeof(listCertStore) / sizeof(*listCertStore); i < c; i++){ if (strcmp(listCertStore[i].c_str(), strTrust.c_str()) == 0){ trueTrust = true; break; } } if (!trueTrust){ THROW_EXCEPTION(0, Provider_System, NULL, "Category of object is uncorrect"); } int enc; if (itPrivateKey(uri, &enc)){ item->type = new std::string("KEY"); item->uri = uri; item->provider = new std::string("SYSTEM"); item->category = new std::string(strTrust); item->keyEncrypted = enc; item->format = new std::string("PEM"); Handle<std::string> keyHash = new std::string(uri->c_str()); const size_t last_slash_idx = keyHash->find_last_of(CROSSPLATFORM_SLASH); if (std::string::npos != last_slash_idx){ keyHash->erase(0, last_slash_idx + 1); } const size_t period_idx = keyHash->rfind('.'); if (std::string::npos != period_idx){ keyHash->erase(period_idx); } if (keyHash->length() == 40){ item->hash = keyHash; } else{ THROW_EXCEPTION(0, Provider_System, NULL, "Error length hash (need 40 for sha1). Hash is privatekey filename"); } return item; } in->seek(0); LOGGER_OPENSSL(PEM_read_bio_X509); xcert = PEM_read_bio_X509(in->internal(), NULL, NULL, NULL); if (xcert){ hcert = new Certificate(xcert); item->format = new std::string("PEM"); } else{ in->seek(0); LOGGER_OPENSSL(d2i_X509_bio); xcert = d2i_X509_bio(in->internal(), NULL); if (xcert){ hcert = new Certificate(xcert); item->format = new std::string("DER"); } } if (!hcert.isEmpty()){ item->type = new std::string("CERTIFICATE"); item->uri = uri; item->provider = new std::string("SYSTEM"); item->category = new std::string(strTrust); char * hexHash; Handle<std::string> hhash = hcert->getThumbprint(); PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash); item->hash = new std::string(hexHash); item->certSubjectName = hcert->getSubjectName(); item->certSubjectFriendlyName = hcert->getSubjectFriendlyName(); item->certIssuerName = hcert->getIssuerName(); item->certIssuerFriendlyName = hcert->getIssuerFriendlyName(); item->certSerial = hcert->getSerialNumber(); item->certOrganizationName = hcert->getOrganizationName(); item->certSignatureAlgorithm = hcert->getSignatureAlgorithm(); item->certNotBefore = hcert->getNotBefore(); item->certNotAfter = hcert->getNotAfter(); item->certKey = getKey(uri); return item; } in->seek(0); LOGGER_OPENSSL(PEM_read_bio_X509_REQ); xreq = PEM_read_bio_X509_REQ(in->internal(), NULL, NULL, NULL); if (xreq){ item->format = new std::string("PEM"); } else{ in->seek(0); LOGGER_OPENSSL(d2i_X509_REQ_bio); xreq = d2i_X509_REQ_bio(in->internal(), NULL); if (xreq){ item->format = new std::string("DER"); } } if (xreq){ item->type = new std::string("REQUEST"); item->uri = uri; item->provider = new std::string("SYSTEM"); item->category = new std::string(strTrust); /* SHA-1 hash */ unsigned char hash[EVP_MAX_MD_SIZE] = { 0 }; unsigned int hashlen = 0; LOGGER_OPENSSL(X509_digest); if (!X509_REQ_digest(xreq, EVP_sha1(), hash, &hashlen)) { THROW_OPENSSL_EXCEPTION(0, Provider_System, NULL, "X509_REQ_digest"); } Handle<std::string> hhash = new std::string((char *)hash, hashlen); char * hexHash; PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash); item->hash = new std::string(hexHash); /* Request subject name */ LOGGER_OPENSSL(X509_REQ_get_subject_name); X509_NAME *name = X509_REQ_get_subject_name(xreq); if (!name){ THROW_EXCEPTION(0, Provider_System, NULL, "X509_NAME is NULL"); } LOGGER_OPENSSL(X509_NAME_oneline_ex); std::string str_name = X509_NAME_oneline_ex(name); Handle<std::string> nameRes = new std::string(str_name.c_str(), str_name.length()); item->csrSubjectName = nameRes; /* Request subject friendly name */ Handle<std::string> friendlyName = new std::string(""); int nid = NID_commonName; LOGGER_OPENSSL(X509_NAME_get_index_by_NID); int index = X509_NAME_get_index_by_NID(name, nid, -1); if (index >= 0) { LOGGER_OPENSSL(X509_NAME_get_entry); X509_NAME_ENTRY *issuerNameCommonName = X509_NAME_get_entry(name, index); if (issuerNameCommonName) { LOGGER_OPENSSL(X509_NAME_ENTRY_get_data); ASN1_STRING *issuerCNASN1 = X509_NAME_ENTRY_get_data(issuerNameCommonName); if (issuerCNASN1 != NULL) { unsigned char *utf = NULL; LOGGER_OPENSSL(ASN1_STRING_to_UTF8); ASN1_STRING_to_UTF8(&utf, issuerCNASN1); friendlyName = new std::string((char *)utf); OPENSSL_free(utf); } } } else { friendlyName = new std::string("No common name"); } item->csrSubjectFriendlyName = friendlyName; item->csrKey = getKey(uri); return item; } in->seek(0); LOGGER_OPENSSL(PEM_read_bio_X509_CRL); xcrl = PEM_read_bio_X509_CRL(in->internal(), NULL, NULL, NULL); if (xcrl){ hcrl = new CRL(xcrl); item->format = new std::string("PEM"); } else{ in->seek(0); LOGGER_OPENSSL(d2i_X509_CRL_bio); xcrl = d2i_X509_CRL_bio(in->internal(), NULL); if (xcrl){ hcrl = new CRL(xcrl); item->format = new std::string("DER"); } } if (!hcrl.isEmpty()){ item->type = new std::string("CRL"); item->uri = uri; item->provider = new std::string("SYSTEM"); item->category = new std::string(strTrust); char * hexHash; Handle<std::string> hhash = hcrl->getThumbprint(); PkiStore::bin_to_strhex((unsigned char *)hhash->c_str(), hhash->length(), &hexHash); item->hash = new std::string(hexHash); item->crlIssuerName = hcrl->issuerName(); item->crlIssuerFriendlyName = hcrl->issuerFriendlyName(); item->crlLastUpdate = hcrl->getThisUpdate(); item->crlNextUpdate = hcrl->getNextUpdate(); return item; } } catch (Handle<Exception> e){ THROW_EXCEPTION(0, Provider_System, e, "Object type not supported"); } if (item->type->length() == 0){ return NULL; } }
unsigned char *SCEP_MSG_decrypt( SCEP_MSG *msg, EVP_PKEY *ppkey, X509 *cert, long *len ) { char *ret = NULL; char *data = NULL; BIO *bio = NULL; BIO *bio_err = NULL; BIO *bio_dup = NULL; X509 *foo_cert = NULL; EVP_PKEY *pkey = NULL; SCEP_RECIP_INFO *rinfo; if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); /* Get the recipient information to build the fake * certificate needed into the PKCS7_decrypt function */ rinfo = &(msg->env_data.recip_info); /* We need a private key */ if( ppkey ) pkey = ppkey; else pkey = msg->signer_pkey; if( !pkey ) return (NULL); if( cert ) { foo_cert = cert; } else { if( (foo_cert = X509_new()) == NULL ) { BIO_printf(bio_err, "%s:%d: foo_cert not alloc\n", __FILE__, __LINE__); goto err; }; X509_set_issuer_name(foo_cert,rinfo->ias->issuer); X509_set_subject_name(foo_cert,rinfo->ias->issuer); X509_set_serialNumber(foo_cert,rinfo->ias->serial); X509_set_pubkey(foo_cert, pkey); } bio = BIO_new(BIO_s_mem()); if (PKCS7_decrypt( msg->env_data.p7env, pkey, foo_cert, bio, 0) == 0) { // printf("%s:%d: decryption failed\n", __FILE__, // __LINE__); goto err; } BIO_flush(bio); if( len ) *len = BIO_get_mem_data(bio, &data); switch ( msg->messageType ) { case MSG_CERTREP: if( msg->env_data.crl = d2i_X509_CRL_bio(bio,NULL) ) { /* There is a CRL */ ret = (char *) msg->env_data.crl; } // p7 = d2i_PKCS7_bio(bio, NULL); break; case MSG_PKCSREQ: msg->env_data.content.req = d2i_X509_REQ_bio(bio, NULL); ret = (char *) msg->env_data.content.req; break; case MSG_GETCERTINITIAL: // req->rd.is = d2i_issuer_and_subject_bio(bio, NULL); break; case MSG_GETCERT: case MSG_GETCRL: msg->env_data.content.ias = d2i_PKCS7_ias_bio(NULL, bio); ret = (char *) msg->env_data.content.ias; break; case MSG_V2PROXY: // unsupported case MSG_V2REQUEST: // unsupported default: // BIO_printf(bio_err, "%s:%d: unknown message type: %s\n", // __FILE__, __LINE__, msg->messageType); break; } err: if( foo_cert && !cert ) X509_free( foo_cert ); if( bio ) BIO_free(bio); ERR_clear_error(); return ret; }