// 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); }
BSONObj createCertificateRequest(const BSONObj& a, void* data) { #ifndef MONGO_CONFIG_SSL return BSON( "" << BSON("ok" << false << "errmsg" << "Cannot create a certificate signing request without SSL support")); #else if (a.nFields() != 1 || a.firstElement().type() != Object) { return BSON( "" << BSON("ok" << false << "errmsg" << "createCertificateRequest requires a single object argument")); } // args can optionally contain some to be determined fields... BSONObj args = a.firstElement().embeddedObject(); if (!args.hasField("CN")) { return BSON( "" << BSON("ok" << false << "errmsg" << "createCertificateRequest requires a Common Name (\"CN\") field")); } // Generate key pair and certificate signing request RSA* rsa; EVP_PKEY* pkey; X509_REQ* x509req; X509_NAME* name; BIO* out; char client_key[2048]; char client_csr[2048]; pkey = EVP_PKEY_new(); if (!pkey) { return BSON("" << BSON("ok" << false)); // fail("couldn't generate key"); } rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL); if (!EVP_PKEY_assign_RSA(pkey, rsa)) { return BSON("" << BSON("ok" << false)); // fail("couldn't assign the key"); } x509req = X509_REQ_new(); X509_REQ_set_pubkey(x509req, pkey); name = X509_NAME_new(); X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char*)"IS", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (const unsigned char*)"MongoDB", -1, -1, 0); X509_NAME_add_entry_by_txt( name, "OU", MBSTRING_ASC, (const unsigned char*)"SkunkWorks client", -1, -1, 0); X509_NAME_add_entry_by_txt( name, "CN", MBSTRING_ASC, (const unsigned char*)args.getStringField("CN"), -1, -1, 0); X509_REQ_set_subject_name(x509req, name); X509_REQ_set_version(x509req, 2); if (!X509_REQ_sign(x509req, pkey, EVP_sha1())) { return BSON("" << BSON("ok" << false)); } // out = BIO_new_file("client.key.pem", "wb"); out = BIO_new(BIO_s_mem()); if (!PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL)) { return BSON("" << BSON("ok" << false)); // fail("can't write private key"); } int i = BIO_read(out, &client_key, sizeof client_key); client_key[i] = '\0'; BIO_free_all(out); out = BIO_new(BIO_s_mem()); if (!PEM_write_bio_X509_REQ_NEW(out, x509req)) { return BSON("" << BSON("ok" << false)); // fail("coudln't write csr"); } i = BIO_read(out, &client_csr, sizeof client_csr); client_csr[i] = '\0'; BIO_free_all(out); EVP_PKEY_free(pkey); X509_REQ_free(x509req); return BSON("" << BSON("ok" << true << "certificateRequest" << client_csr << "privateKey" << client_key)); #endif }
/* Creates an X509 certificate request (2nd stage). */ int MakeCertificateRequest2(unsigned char *reqbuf, int *reqlen, char *x500dn, EVP_PKEY *usrkey) { X509 *racert = NULL; EVP_PKEY *rakey = NULL; X509_REQ *x = NULL; X509_NAME *subject = NULL; unsigned char *p = NULL; int ret, len; if (reqbuf == NULL || reqlen == NULL || x500dn == NULL || usrkey == NULL) return OPENSSLCA_ERR_ARGS; /* Create new request */ if ((x = X509_REQ_new()) == NULL) { ret = OPENSSLCA_ERR_REQ_NEW; goto err; } /* Set public key in request */ if (X509_REQ_set_pubkey(x, usrkey) != 1) { ret = OPENSSLCA_ERR_REQ_SET_PUBKEY; goto err; } /* Set subject name */ subject = X509_REQ_get_subject_name(x); if (subject == NULL) { ret = OPENSSLCA_ERR_REQ_GET_SUBJECT; goto err; } ret = dn2subject(x500dn, subject); if (ret != OPENSSLCA_NO_ERR) goto err; if (caIni.signRequests) { /* Sign request with RA's private key */ ret = read_key(&rakey, CA_PATH(caIni.raKeyFile), caIni.raKeyPasswd); if (ret != OPENSSLCA_NO_ERR) goto err; if (!X509_REQ_sign(x, rakey, EVP_sha1())) { ret = OPENSSLCA_ERR_REQ_SIGN; goto err; } if (caIni.verifyAfterSign) { /* Get RA's public key */ /* TODO: Validate RA certificate */ ret = read_cert(&racert, CA_PATH(caIni.raCertFile)); if (ret != OPENSSLCA_NO_ERR) goto err; EVP_PKEY_free(rakey); if ((rakey = X509_get_pubkey(racert)) == NULL) { ret = OPENSSLCA_ERR_CERT_GET_PUBKEY; goto err; } /* Verify signature on request */ if (X509_REQ_verify(x, rakey) != 1) { ret = OPENSSLCA_ERR_REQ_VERIFY; goto err; } } } #ifdef _DEBUG /* Output request in PEM format */ { FILE *fp = fopen(DBG_PATH("request.pem"), "w"); if (fp != NULL) { X509_REQ_print_fp(fp, x); PEM_write_X509_REQ(fp, x); fclose(fp); } } #endif /* Encode request into DER format */ len = i2d_X509_REQ(x, NULL); if (len < 0) { ret = OPENSSLCA_ERR_REQ_ENCODE; goto err; } if (len > *reqlen) { ret = OPENSSLCA_ERR_BUF_TOO_SMALL; goto err; } *reqlen = len; p = reqbuf; i2d_X509_REQ(x, &p); err: if (racert) X509_free(racert); if (rakey) EVP_PKEY_free(rakey); if (x) X509_REQ_free(x); return ret; }
uint32 CRegProtocol::GenerateCertRequest(char *SubjName, uchar **Cert, uint32 *CertLength) { uint32 err; //= TU_ERROR_CRYPTO_FAILED; X509_REQ *req; X509_NAME *subj; EVP_PKEY *pkey; int nid; X509_NAME_ENTRY *ent; FILE *fp; int fsize; //First, get the private key err = GetPrivateKey(SubjName, TU_KEY_ENC, &pkey); if(TU_SUCCESS != err) { TUTRACE((TUTRACE_ERR, "PROTO: Error getting private key\n")); goto EXIT; } //Now create a new request object if(!(req = X509_REQ_new())) { TUTRACE((TUTRACE_ERR, "PROTO: Error creating new X509 Request\n")); goto ERR_PKEY; } //assign the public key to the request X509_REQ_set_pubkey (req, pkey); //Subject name processing. if(!(subj = X509_NAME_new())) { TUTRACE((TUTRACE_ERR, "PROTO: Error creating new X509 Subject\n")); goto ERR_REQ; } //First set the predefined subject fields for (int i = 0; i < ENTRY_COUNT; i++) { if((nid = OBJ_txt2nid (entries[i].key)) == NID_undef) { TUTRACE((TUTRACE_ERR, "PROTO: Error getting NID from text\n")); X509_NAME_free(subj); goto ERR_REQ; } if(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, (uchar *)entries[i].value, -1))) { TUTRACE((TUTRACE_ERR, "PROTO: Error creating name entry\n")); X509_NAME_free(subj); goto ERR_REQ; } if(X509_NAME_add_entry(subj, ent, -1, 0) != 1) { TUTRACE((TUTRACE_ERR, "PROTO: Error adding name entry to subject\n")); X509_NAME_ENTRY_free(ent); X509_NAME_free(subj); goto ERR_REQ; } }//for //Next set the common name and description if((nid = OBJ_txt2nid("commonName")) == NID_undef) { TUTRACE((TUTRACE_ERR, "PROTO: Error getting NID from text\n")); X509_NAME_free(subj); goto ERR_REQ; } if(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, (uchar *)SubjName, -1))) { TUTRACE((TUTRACE_ERR, "PROTO: Error creating name entry\n")); X509_NAME_free(subj); goto ERR_REQ; } if(X509_NAME_add_entry(subj, ent, -1, 0) != 1) { TUTRACE((TUTRACE_ERR, "PROTO: Error adding name entry to subject\n")); X509_NAME_ENTRY_free(ent); X509_NAME_free(subj); goto ERR_REQ; } //Finally add the subject to the request if(X509_REQ_set_subject_name (req, subj) != 1) { TUTRACE((TUTRACE_ERR, "PROTO: Error setting subject in request\n")); X509_NAME_free(subj); goto ERR_REQ; } //Sign the request if(!(X509_REQ_sign(req, pkey, EVP_sha1()))) { TUTRACE((TUTRACE_ERR, "PROTO: Error signing request\n")); goto ERR_REQ; } //Now we need to serialize the request. So write it to a file and read it out if(!(fp = fopen("protofile", "w"))) { TUTRACE((TUTRACE_ERR, "PROTO: Error opening file for writing\n")); err = TU_ERROR_FILEOPEN; goto ERR_REQ; } if(PEM_write_X509_REQ(fp, req) != 1) { TUTRACE((TUTRACE_ERR, "PROTO: Error writing request to file\n")); err = TU_ERROR_FILEWRITE; fclose(fp); goto ERR_REQ; } fclose(fp); //now open it for reading in binary format if(!(fp = fopen("protofile", "rb"))) { TUTRACE((TUTRACE_ERR, "PROTO: Error opening file for reading\n")); err = TU_ERROR_FILEOPEN; goto ERR_FILE; } //get the filesize fseek(fp, 0, SEEK_END); fsize = ftell(fp); if(fsize == -1) { TUTRACE((TUTRACE_ERR, "Couldn't determine file size\n")); err = TU_ERROR_FILEREAD; goto ERR_FILE; } //Allocate memory *Cert = (uchar *)malloc(fsize); if(!*Cert) { TUTRACE((TUTRACE_ERR, "PROTO: Error allocating memory for cert buffer\n")); err = TU_ERROR_OUT_OF_MEMORY; goto ERR_FILE; } *CertLength = fsize; rewind(fp); fread(*Cert, 1, fsize, fp); err = TU_SUCCESS; ERR_FILE: if(fp) fclose(fp); remove("protofile"); ERR_REQ: X509_REQ_free(req); ERR_PKEY: EVP_PKEY_free(pkey); EXIT: return err; }//GenerateCertRequest
int genrequest(char department[], char cname0[]) { X509_REQ *webrequest = NULL; EVP_PKEY *pubkey = NULL; X509_NAME *reqname = NULL; DSA *mydsa = NULL; RSA *myrsa = NULL; BIO *outbio = NULL; X509_NAME_ENTRY *e; int i; FILE *fp, *fp2; char buf[80] = ""; char country[81] = "UK"; char province[81] = "Gloucestershire"; char locality[81] = "Tetbury"; char organisation[81] = "TETBURY SOFTWARE SERVICES Ltd"; char email_addr[81] = "*****@*****.**"; char cname1[81] = ""; char cname2[81] = ""; char surname[81] = ""; char givenname[81] = ""; char keytype[81] = "rsa"; int rsastrength = 4096; int dsastrength = 0; /* we do not accept requests with no data, i.e. being empty with just a public key. Although technically possible to sign and create a cert, they don't make much sense. We require here at least one CN supplied. */ if(strlen(cname0) == 0 && strlen(cname1) == 0 && strlen(cname2) == 0) printf("Error supply at least one CNAME in request subject"); /* -------------------------------------------------------------------------- * * These function calls are essential to make many PEM + other openssl * * functions work. It is not well documented, I found out after looking into * * the openssl source directly. * * needed by: PEM_read_PrivateKey(), X509_REQ_verify() ... * * -------------------------------------------------------------------------- */ OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* ------------------------------------------------------------------------- * * Generate the key pair based on the selected keytype * * ------------------------------------------------------------------------- */ if ((pubkey=EVP_PKEY_new()) == NULL) printf("Error creating EVP_PKEY structure."); if(strcmp(keytype, "rsa") == 0) { myrsa = RSA_new(); if (! (myrsa = RSA_generate_key(rsastrength, RSA_F4, NULL, NULL))) printf("Error generating the RSA key."); if (!EVP_PKEY_assign_RSA(pubkey,myrsa)) printf("Error assigning RSA key to EVP_PKEY structure."); } else if(strcmp(keytype, "dsa") == 0) { mydsa = DSA_new(); mydsa = DSA_generate_parameters(dsastrength, NULL, 0, NULL, NULL, NULL, NULL); if (! (DSA_generate_key(mydsa))) printf("Error generating the DSA key."); if (!EVP_PKEY_assign_DSA(pubkey,mydsa)) printf("Error assigning DSA key to EVP_PKEY structure."); } else printf("Error: Wrong keytype - choose either RSA or DSA."); /* ------------------------------------------------------------------------- * * Generate the certificate request from scratch * * ------------------------------------------------------------------------- */ if ((webrequest=X509_REQ_new()) == NULL) printf("Error creating new X509_REQ structure."); if (X509_REQ_set_pubkey(webrequest, pubkey) == 0) printf("Error setting public key for X509_REQ structure."); if ((reqname=X509_REQ_get_subject_name(webrequest)) == NULL) printf("Error setting public key for X509_REQ structure."); /* The following functions create and add the entries, working out * * the correct string type and performing checks on its length. * * We also check the return value for errors... */ if(strlen(country) != 0) X509_NAME_add_entry_by_txt(reqname,"C", MBSTRING_ASC, (unsigned char*) country, -1, -1, 0); if(strlen(province) != 0) X509_NAME_add_entry_by_txt(reqname,"ST", MBSTRING_ASC, (unsigned char *) province, -1, -1, 0); if(strlen(locality) != 0) X509_NAME_add_entry_by_txt(reqname,"L", MBSTRING_ASC, (unsigned char *) locality, -1, -1, 0); if(strlen(organisation) != 0) X509_NAME_add_entry_by_txt(reqname,"O", MBSTRING_ASC, (unsigned char *) organisation, -1, -1, 0); if(strlen(department) != 0) X509_NAME_add_entry_by_txt(reqname,"OU", MBSTRING_ASC, (unsigned char *) department, -1, -1, 0); if(strlen(email_addr) != 0) X509_NAME_add_entry_by_txt(reqname,"emailAddress", MBSTRING_ASC, (unsigned char *) email_addr, -1, -1, 0); if(strlen(cname0) != 0) X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC, (unsigned char *) cname0, -1, -1, 0); if(strlen(cname1) != 0) X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC, (unsigned char *) cname1, -1, -1, 0); if(strlen(cname2) != 0) X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC, (unsigned char *) cname2, -1, -1, 0); if(strlen(surname) != 0) X509_NAME_add_entry_by_txt(reqname,"SN", MBSTRING_ASC, (unsigned char *) surname, -1, -1, 0); if(strlen(givenname) != 0) X509_NAME_add_entry_by_txt(reqname,"GN", MBSTRING_ASC, (unsigned char *) givenname, -1, -1, 0); /* ------------------------------------------------------------------------- * * Sign the certificate request: md5 for RSA keys, dss for DSA keys * * ------------------------------------------------------------------------- */ if(strcmp(keytype, "rsa") == 0) { if (!X509_REQ_sign(webrequest,pubkey,EVP_md5())) printf("Error MD5 signing X509_REQ structure."); } else if(strcmp(keytype, "dsa") == 0) { if (!X509_REQ_sign(webrequest,pubkey,EVP_dss())) printf("Error DSS signing X509_REQ structure."); } /* ------------------------------------------------------------------------- * * and sort out the content plus start the html output * * ------------------------------------------------------------------------- */ if (! (fp=fopen("clave_publica.pem", "w"))) printf("No puedo crear el fichero de la request"); if (! (fp2=fopen("clave_privada.pem", "w"))) printf("No puedo crear el fichero de la clave privada"); outbio = BIO_new(BIO_s_file()); BIO_set_fp(outbio, fp, BIO_NOCLOSE); if (! PEM_write_bio_X509_REQ(outbio, webrequest)) printf("Error printing the request"); for (i = 0; i < X509_NAME_entry_count(reqname); i++) { e = X509_NAME_get_entry(reqname, i); OBJ_obj2txt(buf, 80, e->object, 0); } PEM_write_PrivateKey(fp2,pubkey,NULL,NULL,0,0,NULL); BIO_free(outbio); fclose(fp); fclose(fp2); return(0); }
bool avjackif::async_register_new_user(std::string user_name, boost::asio::yield_context yield_context) { // 先发 client_hello if( m_shared_key.empty()) async_client_hello(yield_context); auto digest = EVP_sha1(); // 先生成 RSA 密钥 _rsa.reset(RSA_generate_key(2048, 65537, 0, 0), RSA_free); // 然后生成 CSR boost::shared_ptr<X509_REQ> csr(X509_REQ_new(), X509_REQ_free); boost::shared_ptr<EVP_PKEY> pkey(EVP_PKEY_new(), EVP_PKEY_free); EVP_PKEY_set1_RSA(pkey.get(), _rsa.get()); // 添加证书申请信息 auto subj =X509_REQ_get_subject_name(csr.get()); /* X509_NAME_add_entry_by_NID(subj, NID_countryName, "CN"); X509_NAME_add_entry_by_NID(subj, NID_stateOrProvinceName, "Shanghai"); X509_NAME_add_entry_by_NID(subj, NID_localityName, "Shanghai"); X509_NAME_add_entry_by_NID(subj, NID_organizationName, "avplayer"); X509_NAME_add_entry_by_NID(subj, NID_organizationalUnitName, "sales"); */ X509_NAME_add_entry_by_NID(subj, NID_commonName, user_name); // X509_NAME_add_entry_by_NID(subj, NID_pkcs9_emailAddress, "test-client"); X509_REQ_set_pubkey(csr.get(), pkey.get()); // 签出 CSR X509_REQ_sign(csr.get(), pkey.get(), digest); unsigned char * out = NULL; auto csr_out_len = i2d_X509_REQ(csr.get(), &out); std::string csrout((char*)out, csr_out_len); OPENSSL_free(out); out = NULL; auto rsa_key_out_len = i2d_RSA_PUBKEY(_rsa.get(), &out); std::string rsa_key((char*)out, rsa_key_out_len); OPENSSL_free(out); PEM_write_X509_REQ(stderr, csr.get()); // 然后发送 注册信息 proto::user_register user_register; user_register.set_user_name(user_name); user_register.set_rsa_pubkey(rsa_key); user_register.set_csr(csrout); boost::asio::async_write(*m_sock, boost::asio::buffer(av_router::encode(user_register)), yield_context); // 读取应答 std::unique_ptr<proto::user_register_result> user_register_result((proto::user_register_result*)async_read_protobuf_message(*m_sock, yield_context)); return user_register_result->result() == proto::user_register_result::REGISTER_SUCCEED; }
int CCertificateRequestGenerator::Generate() //Generate certificate request and write into a file { FILE* fp = NULL; char* pbPassword = NULL; EVP_PKEY* pKey = NULL; X509_REQ* pReq = NULL; X509_NAME* pSubj = NULL; const EVP_MD* pDigest = NULL; DWORD bytesWritten; struct entry_pack* pEntPack = NULL; int retFunc = FAIL; //Get command prompt handle HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE); OPENSSL_add_all_algorithms_conf(); ERR_load_crypto_strings(); //First read private key from key file if(!(fp = _tfopen(m_privateKeyFile, _T("r")))) { PrintErrorInfo("Error reading key file!", EGeneric, constparams); WriteConsole(hndl, m_privateKeyFile, wcslen(m_privateKeyFile), &bytesWritten, 0); return retFunc; } if(m_password[0] != 0) { DWORD len = 0; len = _tcslen(m_password); pbPassword = MakeMBCSString(m_password, CP_UTF8, len); pKey = PEM_read_PrivateKey(fp, NULL, NULL, pbPassword); delete pbPassword; } else { pKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL); } fclose(fp); fp = NULL; if(!pKey) { PrintErrorInfo("Error reading private key in key file!", EOPENSSL, constparams); return retFunc; } try { //Create a new cert request and add the public key into it if(!(pReq = X509_REQ_new())) { PrintErrorInfo("Error creating X509 request object!", EOPENSSL, constparams); throw EOPENSSL; } X509_REQ_set_pubkey(pReq, pKey); //Now create DN name entries and assign them to request if(!(pSubj = X509_NAME_new())) { PrintErrorInfo("Error creating X509 name object!", EOPENSSL, constparams); throw EOPENSSL; } //Format DN string DoFormatted(m_dname, &pEntPack); if(pEntPack->num == 0) { PrintErrorInfo("Error formatting Distinguished Name!", EGeneric, constparams); throw EGeneric; } for (int i = 0; i < pEntPack->num; i++) { int nid = 0; DWORD lent = 0; X509_NAME_ENTRY *pEnt = NULL; LPSTR pbMBSTRUTF8 = NULL; if((pEntPack->entries[i].value == NULL) || (pEntPack->entries[i].key == NULL)) { PrintErrorInfo("Error in Distinguished Name construction!", EGeneric, constparams); throw EGeneric; } if((nid = OBJ_txt2nid(pEntPack->entries[i].key)) == NID_undef) { PrintErrorInfo("Error finding NID for a DN entry!", EOPENSSL, constparams); throw EOPENSSL; } lent = _tcslen(pEntPack->entries[i].value); pbMBSTRUTF8 = MakeMBCSString(pEntPack->entries[i].value, CP_UTF8, lent); if(lent > 64) //OpenSSL does not accept a string longer than 64 { if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)"dummy", 5))) { PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams); throw EOPENSSL; } pEnt->value->data = (unsigned char *)malloc(lent+1); for(DWORD j=0; j<lent; j++ ) { pEnt->value->data[j] = pbMBSTRUTF8[j]; } pEnt->value->length = lent; } else if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)pbMBSTRUTF8, lent))) { PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams); throw EOPENSSL; } if(X509_NAME_add_entry(pSubj, pEnt, -1, 0) != 1) { PrintErrorInfo("Error adding entry to X509 Name!", EOPENSSL, constparams); throw EOPENSSL; } delete pbMBSTRUTF8; }//for SYMBIAN_FREE_MEM(pEntPack); if(X509_REQ_set_subject_name(pReq, pSubj) != 1) { PrintErrorInfo("Error adding subject to request!", EOPENSSL, constparams); throw EOPENSSL; } //Find the correct digest and sign the request if(EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA) { pDigest = EVP_dss1(); } else if(EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA) { pDigest = EVP_sha1(); } else { PrintErrorInfo("Error checking private key type!", EOPENSSL, constparams); throw EOPENSSL; } if(!(X509_REQ_sign(pReq, pKey, pDigest))) { PrintErrorInfo("Error signing request!", EOPENSSL, constparams); throw EOPENSSL; } if(!(fp = _tfopen(m_RequestFile, _T("w")))) { PrintErrorInfo("Error writing to request file!",EGeneric,constparams); throw EGeneric; } if(PEM_write_X509_REQ(fp, pReq) != 1) { PrintErrorInfo("Error while writing to request file!", EOPENSSL, constparams); throw EOPENSSL; } //Free variables EVP_PKEY_free(pKey); X509_NAME_free(pSubj); X509_REQ_free(pReq); fclose(fp); _tprintf(_T("\nCreated request: ")); WriteConsole(hndl, m_RequestFile, wcslen(m_RequestFile), &bytesWritten, 0); retFunc = SUCCESS; } catch (...) { if(pKey) { EVP_PKEY_free(pKey); } if(pSubj) { X509_NAME_free(pSubj); } if(pReq) { X509_REQ_free(pReq); } SYMBIAN_FREE_MEM(pEntPack); } return retFunc; }
void LFNetConfigLoader::retrieveConfig() { this->notifyStatus("Loading OpenSSL stuff ..."); OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); this->notifyStatus("Generating private key ..."); BIGNUM* e = BN_new(); BN_set_word(e, RSA_F4); RSA* key = RSA_new(); RSA_generate_key_ex(key, 4096, e, NULL); this->notifyStatus("Saving private key ..."); BIO* privateKey = BIO_new_file((_configLocation + "/private.key").toLocal8Bit().data(), "w"); PEM_write_bio_RSAPrivateKey(privateKey, key, NULL, NULL, 0, NULL, NULL); BIO_free(privateKey); this->notifyStatus("Generating csr ..."); EVP_PKEY* pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, key); X509_NAME* name = X509_NAME_new(); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_UTF8, (unsigned char*)"LF-Net", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8, (unsigned char*)"VPN", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (unsigned char*)(_username.toUpper() + "_" + _computerName.toUpper()).toUtf8().data(), -1, -1, 0); X509_REQ* req = X509_REQ_new(); X509_REQ_set_pubkey(req, pkey); X509_REQ_set_subject_name(req, name); X509_REQ_set_version(req, 1); X509_REQ_sign(req, pkey, EVP_sha512()); BIO* request = BIO_new(BIO_s_mem()); PEM_write_bio_X509_REQ(request, req); BUF_MEM* requestData; BIO_get_mem_ptr(request, &requestData); this->notifyStatus("Request certificate using generated csr ..."); QNetworkAccessManager *mgr = new QNetworkAccessManager(this); connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(certificateRequestFinished(QNetworkReply*))); connect(mgr, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); QNetworkRequest netRequest(QUrl("https://mokoscha.lf-net.org/request_certificate")); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); mgr->post(netRequest, QByteArray(requestData->data, requestData->length)); this->notifyStatus("Cleaning up temporary data ..."); BIO_free(request); X509_REQ_free(req); X509_NAME_free(name); EVP_PKEY_free(pkey); BN_free(e); this->notifyStatus("Waiting for certificate ..."); }
inline void certificate_request::sign(pkey::pkey pkey, hash::message_digest_algorithm algorithm) const { error::throw_error_if_not(X509_REQ_sign(ptr().get(), pkey.raw(), algorithm.raw()) != 0); }
/*** sign x509_req object @function sign @tparam evp_pkey pkey private key which to sign x509_req object @tparam number|string|evp_md md message digest alg used to sign @treturn boolean result true for suceess */ static LUA_FUNCTION(openssl_csr_sign) { X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req"); EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr); if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2)) { EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey"); const EVP_MD* md = get_digest(L, 3, "sha256"); int ret = 1; if (pubkey == NULL) { BIO* bio = BIO_new(BIO_s_mem()); if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1) { pubkey = d2i_PUBKEY_bio(bio, NULL); if (pubkey) { ret = X509_REQ_set_pubkey(csr, pubkey); EVP_PKEY_free(pubkey); } else { ret = 0; } } BIO_free(bio); } else { EVP_PKEY_free(pubkey); } if (ret == 1) ret = X509_REQ_sign(csr, pkey, md); return openssl_pushresult(L, ret); } else if (lua_isstring(L, 2)) { size_t siglen; unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen); const EVP_MD* md = get_digest(L, 3, NULL); ASN1_BIT_STRING *sig = NULL; X509_ALGOR *alg = NULL; luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg); /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */ X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL); ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen); /* * In the interests of compatibility, I'll make sure that the bit string * has a 'not-used bits' value of 0 */ sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); sig->flags |= ASN1_STRING_FLAG_BITS_LEFT; lua_pushboolean(L, 1); return 1; } else { int inl; unsigned char* tosign = NULL; luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!"); inl = i2d_re_X509_REQ_tbs(csr, &tosign); if (inl > 0 && tosign) { lua_pushlstring(L, (const char*)tosign, inl); OPENSSL_free(tosign); return 1; } return openssl_pushresult(L, 0); } }