// confirm certificate signature bool CertDecoder::ConfirmSignature(Source& pub) { HashType ht; mySTL::auto_ptr<HASH> hasher; if (signatureOID_ == MD5wRSA) { hasher.reset(NEW_TC MD5); ht = MD5h; } else if (signatureOID_ == MD2wRSA) { hasher.reset(NEW_TC MD2); ht = MD2h; } else if (signatureOID_ == SHAwRSA || signatureOID_ == SHAwDSA) { hasher.reset(NEW_TC SHA); ht = SHAh; } else { source_.SetError(UNKOWN_SIG_E); return false; } byte digest[SHA::DIGEST_SIZE]; // largest size hasher->Update(source_.get_buffer() + certBegin_, sigIndex_ - certBegin_); hasher->Final(digest); if (keyOID_ == RSAk) { // put in ASN.1 signature format Source build; Signature_Encoder(digest, hasher->getDigestSize(), ht, build); RSA_PublicKey pubKey(pub); RSAES_Encryptor enc(pubKey); return enc.SSL_Verify(build.get_buffer(), build.size(), signature_); } else { // DSA // extract r and s from sequence byte seqDecoded[DSA_SIG_SZ]; DecodeDSA_Signature(seqDecoded, signature_, sigLength_); DSA_PublicKey pubKey(pub); DSA_Verifier ver(pubKey); return ver.Verify(digest, seqDecoded); } }
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { std::vector<valtype> vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == TX_PUBKEY) { CPubKey pubKey(vSolutions[0]); if (!pubKey.IsValid()) return false; addressRet = pubKey.GetID(); return true; } else if (whichType == TX_PUBKEYHASH) { addressRet = CKeyID(uint160(vSolutions[0])); return true; } else if (whichType == TX_SCRIPTHASH) { addressRet = CScriptID(uint160(vSolutions[0])); return true; } // Multisig txns have more than one address... return false; }
bool XeCrypt::Pkcs1Verify(BYTE *pbMessage, DWORD cbMessage, BYTE *pbSignature, DWORD cbSignature, UINT64 publicExponent, BYTE *modulus) { Botan::RSA_PublicKey pubKey(Botan::BigInt::decode(modulus, cbSignature), publicExponent); Botan::PK_Verifier verifier(pubKey, "EMSA3(SHA-160)"); return verifier.verify_message(pbMessage, cbMessage, pbSignature, cbSignature); }
void CToxProto::BootstrapNodesFromIni(bool isIPv6) { if (IsFileExists((TCHAR*)VARST(_T(TOX_INI_PATH)))) { char fileName[MAX_PATH]; mir_strcpy(fileName, VARS(TOX_INI_PATH)); char *section, sections[MAX_PATH], value[MAX_PATH]; GetPrivateProfileSectionNamesA(sections, _countof(sections), fileName); section = sections; while (*section != NULL) { if (strstr(section, TOX_SETTINGS_NODE_PREFIX) == section) { GetPrivateProfileStringA(section, "IPv4", NULL, value, _countof(value), fileName); ptrA address(mir_strdup(value)); int port = GetPrivateProfileIntA(section, "Port", 33445, fileName); GetPrivateProfileStringA(section, "PubKey", NULL, value, _countof(value), fileName); ptrA pubKey(mir_strdup(value)); BootstrapNode(address, port, pubKey); if (isIPv6) { GetPrivateProfileStringA(section, "IPv6", NULL, value, _countof(value), fileName); address = mir_strdup(value); BootstrapNode(address, port, pubKey); } } section += mir_strlen(section) + 1; } } }
void CToxProto::BootstrapNodesFromDb(bool isIPv6) { char module[MAX_PATH]; mir_snprintf(module, "%s_Nodes", m_szModuleName); int nodeCount = db_get_w(NULL, module, TOX_SETTINGS_NODE_COUNT, 0); if (nodeCount > 0) { char setting[MAX_PATH]; for (int i = 0; i < nodeCount; i++) { mir_snprintf(setting, TOX_SETTINGS_NODE_IPV4, i); ptrA address(db_get_sa(NULL, module, setting)); mir_snprintf(setting, TOX_SETTINGS_NODE_PORT, i); int port = db_get_w(NULL, module, setting, 33445); mir_snprintf(setting, TOX_SETTINGS_NODE_PKEY, i); ptrA pubKey(db_get_sa(NULL, module, setting)); BootstrapNode(address, port, pubKey); if (isIPv6) { mir_snprintf(setting, TOX_SETTINGS_NODE_IPV6, i); address = db_get_sa(NULL, module, setting); BootstrapNode(address, port, pubKey); } } } }
SECStatus VerifySignedData(const CERTSignedData* sd, const CERTCertificate* cert, void* pkcs11PinArg) { if (!sd || !sd->data.data || !sd->signatureAlgorithm.algorithm.data || !sd->signature.data || !cert) { PR_NOT_REACHED("invalid args to VerifySignedData"); PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } // See bug 921585. if (sd->data.len > static_cast<unsigned int>(std::numeric_limits<int>::max())) { PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } // convert sig->len from bit counts to byte count. SECItem sig = sd->signature; DER_ConvertBitString(&sig); // Use SECKEY_ExtractPublicKey instead of CERT_ExtractPublicKey because // CERT_ExtractPublicKey would try to do (EC)DSA parameter inheritance, using // the classic (wrong) NSS path building logic. We intentionally do not // support parameter inheritance. ScopedSECKEYPublicKey pubKey(SECKEY_ExtractPublicKey(&cert->subjectPublicKeyInfo)); if (!pubKey) { return SECFailure; } SECOidTag hashAlg; if (VFY_VerifyDataWithAlgorithmID(sd->data.data, static_cast<int>(sd->data.len), pubKey.get(), &sig, &sd->signatureAlgorithm, &hashAlg, pkcs11PinArg) != SECSuccess) { return SECFailure; } // TODO: Ideally, we would do this check before we call // VFY_VerifyDataWithAlgorithmID. But, VFY_VerifyDataWithAlgorithmID gives us // the hash algorithm so it is more convenient to do things in this order. uint32_t policy; if (NSS_GetAlgorithmPolicy(hashAlg, &policy) != SECSuccess) { return SECFailure; } // XXX: I'm not sure why there isn't NSS_USE_ALG_IN_SSL_SIGNATURE, but there // isn't. Since we don't know the context in which we're being called, be as // strict as we can be given the NSS API that is available. static const uint32_t requiredPolicy = NSS_USE_ALG_IN_CERT_SIGNATURE | NSS_USE_ALG_IN_CMS_SIGNATURE; if ((policy & requiredPolicy) != requiredPolicy) { PR_SetError(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, 0); return SECFailure; } return SECSuccess; }
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { std::vector<valtype> vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; if (whichType == TX_PUBKEY) { CPubKey pubKey(vSolutions[0]); if (!pubKey.IsValid()) return false; addressRet = pubKey.GetID(); return true; } else if (whichType == TX_PUBKEYHASH) { addressRet = CKeyID(uint160(vSolutions[0])); return true; } else if (whichType == TX_SCRIPTHASH) { addressRet = CScriptID(uint160(vSolutions[0])); return true; } else if (whichType == TX_WITNESS_V0_KEYHASH) { WitnessV0KeyHash hash; std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); addressRet = hash; return true; } else if (whichType == TX_WITNESS_V0_SCRIPTHASH) { WitnessV0ScriptHash hash; std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); addressRet = hash; return true; } else if (whichType == TX_WITNESS_UNKNOWN) { WitnessUnknown unk; unk.version = vSolutions[0][0]; std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program); unk.length = vSolutions[1].size(); addressRet = unk; return true; } // Multisig txns have more than one address... return false; }
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet) { addressRet.clear(); typeRet = TX_NONSTANDARD; std::vector<valtype> vSolutions; if (!Solver(scriptPubKey, typeRet, vSolutions)) return false; if (typeRet == TX_NULL_DATA){ // This is data, not addresses return false; } if (typeRet == TX_MULTISIG) { nRequiredRet = vSolutions.front()[0]; for (unsigned int i = 1; i < vSolutions.size()-1; i++) { CPubKey pubKey(vSolutions[i]); if (!pubKey.IsValid()) continue; CTxDestination address = pubKey.GetID(); addressRet.push_back(address); } if (addressRet.empty()) return false; } else { nRequiredRet = 1; CTxDestination address; if (!ExtractDestination(scriptPubKey, address)) return false; addressRet.push_back(address); } return true; }
// Try to decrypt the file using the given key. If thorough is true then // the entire file is read into memory. Returns true if decryption was // successful. bool cFileManipulator::TestDecryption(const cElGamalSigPublicKey& key, bool thorough) { // TODO: pay attention to thorough flag. For now we will just always act thoroughly. ASSERT(mbInit); if (!mbInit) { return false; } bool fError = false; // "turn down" the verbosity of iUserNotify to V_NORMAL it it is V_VERBOSE to make output a little cleaner bool fChangedVerbosity = false; int savedVerbosity = iUserNotify::GetInstance()->GetVerboseLevel(); if (savedVerbosity == iUserNotify::V_VERBOSE) { iUserNotify::GetInstance()->SetVerboseLevel(iUserNotify::V_NORMAL); fChangedVerbosity = true; } try { if (mFileHeader.GetID() == cFCODatabaseFile::GetFileHeaderID()) { cFCODatabaseFile db; bool encrypted; cTWUtil::ReadDatabase(mFileName.c_str(), db, &key, encrypted); } else if (mFileHeader.GetID() == cFCOReport::GetFileHeaderID()) { cFCOReport rep; cFCOReportHeader reph; bool encrypted; cTWUtil::ReadReport(mFileName.c_str(), reph, rep, &key, true, encrypted); } else if (mFileHeader.GetID() == cConfigFile::GetFileHeaderID()) { // read the embedded key from config file and see if it is the same // as the public key passed in. cMemoryArchive memArch; TSTRING configText; //not used cTWUtil::ReadConfigText(mFileName.c_str(), configText, &memArch); memArch.Seek(0, cBidirArchive::BEGINNING); // only do the test if there is baggage (indicating the cfg file is encrypted) if (memArch.Length() > 0) { // create the two public keys... cElGamalSigPublicKey pubKey(memArch.GetMemory()); // compare the two .... if (!pubKey.IsEqual(key)) throw ePoly(); } } else if (mFileHeader.GetID() == cPolicyFile::GetFileHeaderID()) { std::string policyText; cTWUtil::ReadPolicyText(mFileName.c_str(), policyText, &key); } else throw ePoly(); } catch (eError&) { fError = true; } // reset verbosity if (fChangedVerbosity) iUserNotify::GetInstance()->SetVerboseLevel(savedVerbosity); return (fError == false); }
// Convert an opaque key handle aKeyHandle back into a Private Key object, using // the long-lived aPersistentKey mixed with aAppParam and the AES Key Wrap // algorithm. static UniqueSECKEYPrivateKey PrivateKeyFromKeyHandle(const UniquePK11SlotInfo& aSlot, const UniquePK11SymKey& aPersistentKey, uint8_t* aKeyHandle, uint32_t aKeyHandleLen, uint8_t* aAppParam, uint32_t aAppParamLen, const nsNSSShutDownPreventionLock&) { MOZ_ASSERT(aSlot); MOZ_ASSERT(aPersistentKey); MOZ_ASSERT(aKeyHandle); MOZ_ASSERT(aAppParam); MOZ_ASSERT(aAppParamLen == SHA256_LENGTH); if (NS_WARN_IF(!aSlot || !aPersistentKey || !aKeyHandle || !aAppParam || aAppParamLen != SHA256_LENGTH)) { return nullptr; } // As we only support one key format ourselves (right now), fail early if // we aren't that length if (NS_WARN_IF(aKeyHandleLen != kVersion1KeyHandleLen)) { return nullptr; } if (NS_WARN_IF(aKeyHandle[0] != SoftTokenHandle::Version1)) { // Unrecognized version return nullptr; } uint8_t saltLen = aKeyHandle[1]; uint8_t* saltPtr = aKeyHandle + 2; if (NS_WARN_IF(saltLen != kSaltByteLen)) { return nullptr; } // Prepare the HKDF (https://tools.ietf.org/html/rfc5869) CK_NSS_HKDFParams hkdfParams = { true, saltPtr, saltLen, true, aAppParam, aAppParamLen }; SECItem kdfParams = { siBuffer, (unsigned char*)&hkdfParams, sizeof(hkdfParams) }; // Derive a wrapping key from aPersistentKey, the salt, and the aAppParam. // CKM_AES_KEY_GEN and CKA_WRAP are key type and usage attributes of the // derived symmetric key and don't matter because we ignore them anyway. UniquePK11SymKey wrapKey(PK11_Derive(aPersistentKey.get(), CKM_NSS_HKDF_SHA256, &kdfParams, CKM_AES_KEY_GEN, CKA_WRAP, kWrappingKeyByteLen)); if (NS_WARN_IF(!wrapKey.get())) { MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to derive a wrapping key, NSS error #%d", PORT_GetError())); return nullptr; } uint8_t wrappedLen = aKeyHandleLen - saltLen - 2; uint8_t* wrappedPtr = aKeyHandle + saltLen + 2; ScopedAutoSECItem wrappedKeyItem(wrappedLen); memcpy(wrappedKeyItem.data, wrappedPtr, wrappedKeyItem.len); ScopedAutoSECItem pubKey(kPublicKeyLen); UniqueSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD, /* default IV */ nullptr )); CK_ATTRIBUTE_TYPE usages[] = { CKA_SIGN }; int usageCount = 1; UniqueSECKEYPrivateKey unwrappedKey( PK11_UnwrapPrivKey(aSlot.get(), wrapKey.get(), CKM_NSS_AES_KEY_WRAP_PAD, param.get(), &wrappedKeyItem, /* no nickname */ nullptr, /* discard pubkey */ &pubKey, /* not permanent */ false, /* non-exportable */ true, CKK_EC, usages, usageCount, /* wincx */ nullptr)); if (NS_WARN_IF(!unwrappedKey)) { // Not our key. MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Could not unwrap key handle, NSS Error #%d", PORT_GetError())); return nullptr; } return unwrappedKey; }
void UserProcessingCenter::handleKerberosLogin(CMazeMsg* context) { //cout<<":: kerberos login:: "<<endl; debug("kerberos login request"); char *pbuf = context->getMsg(); int rt = context->getLen(); MBlockSocket *pclient = context->getSocket(); UserDatabase *userdb = UserDatabase::getInstance(); KMsgHead kmsghead; if(kmsghead.unserialize(pbuf,rt)!=-1) { switch(kmsghead.msgtype) { case USER_LOGIN_REQUEST: { //cout<<"::kerberos login::"<<endl; UserLoginRequest req; if(req.unserialize(pbuf,rt)!=-1) { USERDB *userinfo = new USERDB; //debug("recv req from user %d to @time %d"<<req.uid<<" "<<req.ts); bool logfind=false; if(req.uid!=0) { debug("recv req from user id to @time--->"<<req.uid<<" "<<req.ts); logfind=(userdb->get_record( req.uid,userinfo) == 0); debug("find user %d 's user info"<<req.uid); } else { debug("recv req from user email to @time---->"<<req.emailAddr<<" "<<req.ts); string emailAddr=req.emailAddr; string badEmail = string("*****@*****.**"); if(emailAddr == badEmail) { cout<<"--------bad email--------"<<endl; logfind = false; } else { logfind=(userdb->get_record(emailAddr,userinfo) == 0); debug("find user %s 's user info"<<emailAddr.c_str()); } } if(logfind) { //generate ticket and send it back to User here... UserLoginReply reply; strncpy(reply.userInfo.NickName,userinfo->NickName,24); strncpy(reply.userInfo.MailAddr,userinfo->MailAddr,128); reply.userInfo.UID=userinfo->UID; reply.userInfo.IP=pclient->GetPeerName().GetIP(); //TODO reply.userInfo.ServerPort=pclient->GetPeerName().GetPort(); //TODO reply.userInfo.Account=userinfo->Account; reply.userInfo.Level=userinfo->Level; reply.userInfo.LastAccountAddTime=(unsigned)userinfo->LastAddAccount; //get user password(key) from user database; string userKey=userinfo->Pwd; //get tgs key from config or database. string tgsKey ="tgskey"; //generate a random string to be the session key shared by user and tgs. string sessionKey=GenRandomKey(); unsigned ts=(unsigned)time(NULL);//the time-stamp of the ticket release. reply.ts =ts; reply.life =TGS_TICKET_LIFE;//the life of the ticket below reply.privilege=0;//TODO privilege of user.. reply.head.src=0; reply.head.dst=req.uid; reply.head.status=0; reply.sessionKey.set(sessionKey.c_str(),sessionKey.length()); Ticket ticket; ticket.uid=req.uid; ticket.uaddr=0; //TODO ticket.ts=ts; ticket.life=TGS_TICKET_LIFE; ticket.privilege=0;//TODO; ticket.sessionKey.set(sessionKey.c_str(),sessionKey.length()); reply.cipheredTicket=ticket.serializeAndEncrypt(tgsKey.c_str(),tgsKey.length()); RawData result=reply.serializeAndEncrypt(userKey.c_str(),userKey.length()); debug("AS:\tGrant ticket and session key {%s} to user %d\n"<<sessionKey.c_str()<<req.uid); unsigned int ip = pclient->GetPeerName().GetIP(); string ip_str=pclient->GetPeerName().ip(); pclient->SendPacket(result.data,result.len); char buf[256]; time_t timep=time(NULL); struct tm *p=localtime(&timep); sprintf(buf,"%d_%0.2d_%0.2d_login.txt",(1900+p->tm_year),(1+p->tm_mon),p->tm_mday); Configuration config = Configuration::getInstance(); string logDir = config.get("log"); string logName = logDir + buf; ofstream loginLogOutput(logName.c_str(),ofstream::app); sprintf(buf,"%.2d:%.2d:%.2d %10d %15s kerbroslogin ",p->tm_hour,p->tm_min,p->tm_sec,userinfo->UID,ip_str.c_str()); loginLogOutput<<buf<<endl; } else { //no user...info... debug("login ip:"<<pclient->GetPeerName().ToString()); debug("no user %d %s info in out database !"<<req.uid<<req.emailAddr); } delete userinfo; //clean resources used above. } break; }//end of case case COMMIT_KEYS_REQUEST: { printf("recv a commit keys request from %d \n",kmsghead.src); RawData reqdata(pbuf,rt); CommitKeysRequest req; string upasswd=userdb->getUserPasswd(kmsghead.src); req.decryptAndUnserialize(reqdata,upasswd.c_str(),upasswd.length()); string pubKey(req.pubKey.data,req.pubKey.len); string privKey(req.privKey.data,req.privKey.len); bool rtv=userdb->putUserKeys(req.head.src,pubKey,privKey); CommitKeysReply reply; reply.head.status=(rtv)?0:-1; RawData replydata=reply.serialize(); pclient->SendPacket(replydata.data,replydata.len); break; }//end of case case PUBLIC_KEY_REQUEST: { debug("recv a public key request from %d"<<kmsghead.src); RawData reqdata(pbuf,rt); PublicKeyRequest req; req.unserialize(reqdata); string pubKey,privKey; bool rtv=userdb->getUserKeys(req.uid,pubKey,privKey); PublicKeyReply reply; reply.pubKey.set(pubKey.c_str(),pubKey.length()); reply.head.status=(rtv)?0:-1; RawData replydata=reply.serialize(); pclient->SendPacket(replydata.data,replydata.len); break; }//end of case case PRIVATE_KEY_REQUEST: { debug("recv a private key request from %d "<<kmsghead.src); RawData reqdata(pbuf,rt); PrivateKeyRequest req; req.unserialize(reqdata); string upasswd=userdb->getUserPasswd(kmsghead.src); string pubKey,privKey; bool rtv=userdb->getUserKeys(kmsghead.src,pubKey,privKey); PrivateKeyReply reply; reply.privKey.set(privKey.c_str(),privKey.length()); RawData replydata=reply.serializeAndEncrypt(upasswd.c_str(),upasswd.length()); pclient->SendPacket(replydata.data,replydata.len); break; } default: break; }//end switch(); }//end if(kmsghead.unserialize().... }
void SecureServer::generateCertificate(const std::string& publicKey, const std::string& privateKey, const std::string& password, const long& secsValid, const std::vector<std::pair<std::string,std::string> >& x509Entries, const std::string& x509Filename) throw (boost::system::system_error) { std::cerr << "generating certificate" << std::endl; std::unique_ptr<X509,void (*)(X509*)> x509(X509_new(), &X509_free); if(ASN1_INTEGER_set(X509_get_serialNumber(x509.get()), std::time(nullptr)) != 1){ throw_system_error_ssl("Could not set X509 parameters"); } X509_gmtime_adj(X509_get_notBefore(x509.get()), 0); X509_gmtime_adj(X509_get_notAfter(x509.get()), secsValid); std::unique_ptr<EVP_PKEY,void(*)(EVP_PKEY*)> privKey(EVP_PKEY_new(), &EVP_PKEY_free); std::unique_ptr<EVP_PKEY,void(*)(EVP_PKEY*)> pubKey(EVP_PKEY_new(), &EVP_PKEY_free); std::unique_ptr<BIO,void (*)(BIO*)> privateBIO(BIO_new_file(privateKey.c_str(), "r"), &BIO_free_all); if(!privateBIO){ throw_system_error_ssl("Could not open "+privateKey+" for reading"); } pem_password_cb* password_cb(nullptr); void *password_u(nullptr); if(!password.empty()){ password_cb = &pemPasswordCBFromString; password_u = (void*)&password; } std::unique_ptr<RSA,void(*)(RSA*)> rsa(PEM_read_bio_RSAPrivateKey(privateBIO.get(), nullptr, password_cb, password_u),&RSA_free); if(!rsa){ throw_system_error_ssl("Could not read PEM RSA private key from "+privateKey); } std::cerr << "read " << privateKey << std::endl; if(EVP_PKEY_set1_RSA(privKey.get(), rsa.get()) != 1){ throw_system_error_ssl("Could not assign EVP_PKEY from RSA private key"); } std::cerr << "assigned EVP_PKEY" << std::endl; std::unique_ptr<BIO,void (*)(BIO*)> publicBIO(BIO_new_file(publicKey.c_str(), "r"), &BIO_free_all); if(!publicBIO){ throw_system_error_ssl("Could not open "+publicKey+" for reading"); } RSA *ptr = rsa.get(); if(PEM_read_bio_RSAPublicKey(publicBIO.get(),&ptr,nullptr,nullptr) == nullptr){ throw_system_error_ssl("Could not read PEM RSA public key from "+publicKey); } std::cerr << "read " << publicKey << std::endl; if(EVP_PKEY_set1_RSA(pubKey.get(), rsa.get()) != 1){ throw_system_error_ssl("Could not assign EVP_PKEY from RSA public key"); } if(X509_set_pubkey(x509.get(), pubKey.get()) != 1){ throw_system_error_ssl("Could nost assign X509 public key from EVP_PKEY"); } X509_NAME *name = X509_get_subject_name(x509.get()); std::cerr << "got subject name" << std::endl; for(const std::pair<std::string,std::string>& entry : x509Entries){ if(X509_NAME_add_entry_by_txt(name, entry.first.c_str(), MBSTRING_ASC, (const unsigned char*)entry.second.c_str(), entry.second.length(), -1, 0) != 1){ throw_system_error_ssl("Could not add X509 entry /"+entry.first+"/ = \""+entry.second+'"'); } std::cerr << "added entry /" << entry.first << "/ = \"" << entry.second << '"' << std::endl; } if(X509_set_issuer_name(x509.get(),name) != 1){ throw_system_error_ssl("Could not set X509 issuer name"); } std::cerr << "set issuer name" << std::endl; std::unique_ptr<EVP_MD_CTX,void(*)(EVP_MD_CTX*)> mctx(EVP_MD_CTX_create(),&EVP_MD_CTX_destroy); // EVP_PKEY_CTX *pkctx(nullptr); if(EVP_DigestSignInit(mctx.get(),nullptr,EVP_sha256(),nullptr,privKey.get()) != 1){ throw_system_error_ssl("Could not init EVP Digest Sign"); } std::cerr << "initialized EVP MD CTX" << std::endl; if(X509_sign_ctx(x509.get(),mctx.get()) <= 0){ throw_system_error_ssl("Could not sign certificate"); } std::cerr << "signed" << std::endl; std::unique_ptr<BIO,void(*)(BIO*)> x509BIO(BIO_new_file(x509Filename.c_str(),"w"),&BIO_free_all); if(PEM_write_bio_X509(x509BIO.get(),x509.get()) != 1){ throw_system_error_ssl("Could not write X509 certificate"); } std::cerr << "written to " << x509Filename << std::endl; }