コード例 #1
0
// 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);
    }
}
コード例 #2
0
ファイル: standard.cpp プロジェクト: syscoin/syscoin2
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;
}
コード例 #3
0
ファイル: XeCrypt.cpp プロジェクト: Overx/Velocity
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);
}
コード例 #4
0
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;
		}
	}
}
コード例 #5
0
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);
			}
		}
	}
}
コード例 #6
0
ファイル: pkixkey.cpp プロジェクト: JuannyWang/gecko-dev
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;
}
コード例 #7
0
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;
}
コード例 #8
0
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;
}
コード例 #9
0
// 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);
}
コード例 #10
0
// 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;
}
コード例 #11
0
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()....
}
コード例 #12
0
	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;
	}