/*** get digest of x509_req @function digest @tparam[opt='SHA1'] evp_md|string md_alg default use sha1 @treturn string digest result */ static LUA_FUNCTION(openssl_csr_digest) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len = sizeof(buf); int ret; const EVP_MD *md = get_digest(L, 2, "sha256"); ret = X509_REQ_digest(csr, md, buf, &len); if (ret == 1) { lua_pushlstring(L, (const char*)buf, len); return 1; } return openssl_pushresult(L, ret); };
static LUA_FUNCTION(openssl_csr_digest) { X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); const EVP_MD *md = NULL; unsigned char buf[EVP_MAX_MD_SIZE]; unsigned int len = sizeof(buf); int ret; if (lua_isnoneornil(L, 2)) md = EVP_get_digestbyname("SHA1"); else md = get_digest(L, 2); ret = X509_REQ_digest(csr, md, buf, &len); if (ret == 1) { lua_pushlstring(L, (const char*)buf, len); return 1; } return openssl_pushresult(L, ret); };
int openssl_x509_cert() { BIO *b; FILE *fp; RSA *rsa; EVP_PKEY *pkey; X509_NAME *name; const EVP_MD *md; X509_REQ *req, **req2; X509_NAME_ENTRY *entry; unsigned int len; char bytes[COMM_LEN]; const unsigned char *pp; unsigned char *p, *der, *mdout, buf[MAX1_LEN]; OpenSSL_add_all_algorithms(); printf("\nX509_Cert info:\n"); return -1; req = X509_REQ_new(); X509_REQ_set_version(req, 1); name = X509_NAME_new(); strcpy(bytes, "beike"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "commonName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 0, -1); strcpy(bytes, "BEIJING"); entry = X509_NAME_ENTRY_create_by_txt(&entry, "countryName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); X509_NAME_add_entry(name, entry, 1, -1); X509_REQ_set_subject_name(req, name); pkey = EVP_PKEY_new(); rsa = RSA_generate_key(LINE_LEN, RSA_3, NULL, NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_REQ_set_pubkey(req, pkey); strcpy(bytes, "USTB"); X509_REQ_add1_attr_by_txt(req, "organizationName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); strcpy(bytes, "TECH"); X509_REQ_add1_attr_by_txt(req, "organizationalUnitName", V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes)); md = EVP_sha1(); X509_REQ_digest(req, md, mdout, &len); X509_REQ_sign(req, pkey, md); b = BIO_new_file("/tmp/certreq.txt", "w"); PEM_write_bio_X509_REQ(b, req); BIO_free(b); len = i2d_X509_REQ(req, NULL); der = (unsigned char *)malloc(len); p = der; len = i2d_X509_REQ(req, &p); X509_REQ_verify(req, pkey); fp = fopen("/tmp/certder.txt", "wb"); fwrite(der, 1, len, fp); fclose(fp); free(der); X509_REQ_free(req); b = BIO_new_file("/tmp/certreq.txt", "r"); PEM_read_bio_X509_REQ(b, NULL, NULL, NULL); fp = fopen("/tmp/certder.txt", "r"); len = fread(buf, 1, MAX1_LEN, fp); fclose(fp); pp = buf; req2 = (X509_REQ **) malloc(sizeof(X509_REQ *)); d2i_X509_REQ(req2, &pp, len); free(req2); X509_REQ_free(*req2); return 0; }
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; } }