void WebRequest::sslClientCert(EVP_PKEY* pkey, scoped_refptr<net::X509Certificate> chain) { base::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> privateKey(pkey); if (privateKey.get() == NULL || chain.get() == NULL) { m_request->ContinueWithCertificate(NULL); return; } GURL gurl(m_url); net::OpenSSLPrivateKeyStore::GetInstance()->StorePrivateKey(gurl, privateKey.release()); m_request->ContinueWithCertificate(chain.release()); }
unsigned char* GKeyPair::powerMod(const unsigned char* pInput, int nInputSize, bool bPublicKey, int* pnOutputSize) { GBigInt input; input.fromByteBuffer(pInput, nInputSize); GBigInt results; results.powerMod(&input, bPublicKey ? publicKey() : privateKey(), n()); *pnOutputSize = results.getUIntCount() * sizeof(unsigned int); unsigned char* pOutput = (unsigned char*)results.toBufferGiveOwnership(); while(pOutput[(*pnOutputSize) - 1] == 0) (*pnOutputSize)--; return pOutput; }
int main(int argc, char **argv) { // Get rid of compiler warning about unused parameters argc = argc; argv = argv; PrivateKey privateKey(argc > 1 ? atoi(argv[1]): 1); std::cout << "Private key: 0x" << privateKey.getValue().get_str(0x10) << std::endl; return 0; }
void InvertibleRSAFunction::DEREncodePrivateKey(BufferedTransformation &bt) const { DERSequenceEncoder privateKey(bt); DEREncodeUnsigned<word32>(privateKey, 0); // version m_n.DEREncode(privateKey); m_e.DEREncode(privateKey); m_d.DEREncode(privateKey); m_p.DEREncode(privateKey); m_q.DEREncode(privateKey); m_dp.DEREncode(privateKey); m_dq.DEREncode(privateKey); m_u.DEREncode(privateKey); privateKey.MessageEnd(); }
/* Generates a public/private key-pair. The keys are retured in a * KeyPair. The generated keys are * 2 * "digitCount" or 2 * "digitCount - 1 digits long, * and have the probability of at least 1 - 4^(-k) of being prime. * For k = 3, that probability is 98.4375%, * and for k = 4 it is 99.609375%. * * k = 3 is recommended by Introduction to Algorithms, Second Edition; * by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and * Clifford Stein for prime number generation. * */ KeyPair RSA::GenerateKeyPair( unsigned long int digitCount, unsigned long int k) { //generate two random numbers p and q, each "digitCount" digits long BigInt p(PrimeGenerator::Generate(digitCount, k)); BigInt q(PrimeGenerator::Generate(digitCount, k)); //make sure they are different while (p == q) { p = PrimeGenerator::Generate(digitCount, k); } //calculate the modulus of both the public and private keys, n BigInt n(p * q); //calculate the totient phi BigInt phi((p - 1) * (q - 1)); //we don't want the keys to be less than 20 bits long if (phi < "1048576") throw "Insufficient key strength!"; //select a small odd integer e that is coprime with phi and e < phi //usually 65537 is used, and we will use it too if it fits //it is recommended that this be the least possible value for e BigInt e("65537"); //make sure the requirements are met while (RSA::GCD(phi, e) != BigIntOne || e < "65537") { PrimeGenerator::makeRandom(e, 5); } //now we have enough information to create the public key //e is the public key exponent, n is the modulus Key publicKey(n, e); //calculate d, de = 1 (mod phi) BigInt d(RSA::solveModularLinearEquation(e, BigIntOne, phi)); //we can create the private key //d is the private key exponent, n is the modulus Key privateKey(n, d); //finally, the keypair is created and returned KeyPair newKeyPair(privateKey, publicKey); return newKeyPair; }
void InvertibleRSAFunction::BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) { BERSequenceDecoder privateKey(bt); word32 version; BERDecodeUnsigned<word32>(privateKey, version, INTEGER, 0, 0); // check version m_n.BERDecode(privateKey); m_e.BERDecode(privateKey); m_d.BERDecode(privateKey); m_p.BERDecode(privateKey); m_q.BERDecode(privateKey); m_dp.BERDecode(privateKey); m_dq.BERDecode(privateKey); m_u.BERDecode(privateKey); privateKey.MessageEnd(); }
int SshConnection::connectHostBased() { qDebug() << "WARNING connectHostBased() not wired correctly"; QString passphrase; QLOG_TRACE() << "SshConnection::connectHostBased"; QString privateKey(getPrivateKeyFile()); QString publicKey(getPublicKeyFile()); int rc; while ((rc = libssh2_userauth_hostbased_fromfile(m_session, m_username.toLatin1().data(), publicKey.toLatin1().data(), privateKey.toLatin1().data(), passphrase.toLatin1().data(), m_hostname.toLatin1().data())) == LIBSSH2_ERROR_EAGAIN); return rc; }
int SshConnection::connectPublicKey() { QLOG_TRACE() << "SshConnection::connectPublicKey"; QString privateKey(getPrivateKeyFile()); QString publicKey(getPublicKeyFile()); qDebug() << "WARNING connectHostBased() not wired correctly"; QString passphrase; int rc; while ((rc = libssh2_userauth_publickey_fromfile(m_session, m_username.toLatin1().data(), publicKey.toLatin1().data(), privateKey.toLatin1().data(), passphrase.toLatin1().data())) == LIBSSH2_ERROR_EAGAIN); if (rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED) rc = LIBSSH2_ERROR_PUBLICKEY_NOT_FOUND; return rc; }
QSslConfiguration Account::getOrCreateSslConfig() { if (!_sslConfiguration.isNull()) { // Will be set by CheckServerJob::finished() // We need to use a central shared config to get SSL session tickets return _sslConfiguration; } // if setting the client certificate fails, you will probably get an error similar to this: // "An internal error number 1060 happened. SSL handshake failed, client certificate was requested: SSL error: sslv3 alert handshake failure" QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration(); QSslCertificate sslClientCertificate; ConfigFile cfgFile; if(!cfgFile.certificatePath().isEmpty() && !cfgFile.certificatePasswd().isEmpty()) { resultP12ToPem certif = p12ToPem(cfgFile.certificatePath().toStdString(), cfgFile.certificatePasswd().toStdString()); QString s = QString::fromStdString(certif.Certificate); QByteArray ba = s.toLocal8Bit(); this->setCertificate(ba, QString::fromStdString(certif.PrivateKey)); } if((!_pemCertificate.isEmpty())&&(!_pemPrivateKey.isEmpty())) { // Read certificates QList<QSslCertificate> sslCertificateList = QSslCertificate::fromData(_pemCertificate, QSsl::Pem); if(sslCertificateList.length() != 0) { sslClientCertificate = sslCertificateList.takeAt(0); } // Read key from file QSslKey privateKey(_pemPrivateKey.toLocal8Bit(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey , ""); // SSL configuration sslConfig.setCaCertificates(QSslSocket::systemCaCertificates()); sslConfig.setLocalCertificate(sslClientCertificate); sslConfig.setPrivateKey(privateKey); qDebug() << "Added SSL client certificate to the query"; } #if QT_VERSION > QT_VERSION_CHECK(5, 2, 0) // Try hard to re-use session for different requests sslConfig.setSslOption(QSsl::SslOptionDisableSessionTickets, false); sslConfig.setSslOption(QSsl::SslOptionDisableSessionSharing, false); sslConfig.setSslOption(QSsl::SslOptionDisableSessionPersistence, false); #endif return sslConfig; }
InvertibleRSAFunction::InvertibleRSAFunction(BufferedTransformation &bt) { BERSequenceDecoder privateKeyInfo(bt); word32 version; BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version if (privateKeyInfo.PeekByte() == INTEGER) { // for backwards compatibility n.BERDecode(privateKeyInfo); e.BERDecode(privateKeyInfo); d.BERDecode(privateKeyInfo); p.BERDecode(privateKeyInfo); q.BERDecode(privateKeyInfo); dp.BERDecode(privateKeyInfo); dq.BERDecode(privateKeyInfo); u.BERDecode(privateKeyInfo); } else { BERSequenceDecoder algorithm(privateKeyInfo); ASN1::rsaEncryption().BERDecodeAndCheck(algorithm); BERDecodeNull(algorithm); algorithm.MessageEnd(); BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); BERSequenceDecoder privateKey(octetString); BERDecodeUnsigned<word32>(privateKey, version, INTEGER, 0, 0); // check version n.BERDecode(privateKey); e.BERDecode(privateKey); d.BERDecode(privateKey); p.BERDecode(privateKey); q.BERDecode(privateKey); dp.BERDecode(privateKey); dq.BERDecode(privateKey); u.BERDecode(privateKey); privateKey.MessageEnd(); octetString.MessageEnd(); } privateKeyInfo.MessageEnd(); }
bool Ssu::registerDevice(QDomDocument *response){ QString certificateString = response->elementsByTagName("certificate").at(0).toElement().text(); QSslCertificate certificate(certificateString.toLatin1()); SsuLog *ssuLog = SsuLog::instance(); SsuCoreConfig *settings = SsuCoreConfig::instance(); if (certificate.isNull()){ // make sure device is in unregistered state on failed registration settings->setValue("registered", false); setError("Certificate is invalid"); return false; } else settings->setValue("certificate", certificate.toPem()); QString privateKeyString = response->elementsByTagName("privateKey").at(0).toElement().text(); QSslKey privateKey(privateKeyString.toLatin1(), QSsl::Rsa); if (privateKey.isNull()){ settings->setValue("registered", false); setError("Private key is invalid"); return false; } else settings->setValue("privateKey", privateKey.toPem()); // oldUser is just for reference purposes, in case we want to notify // about owner changes for the device QString oldUser = response->elementsByTagName("user").at(0).toElement().text(); ssuLog->print(LOG_DEBUG, QString("Old user for your device was: %1").arg(oldUser)); // if we came that far everything required for device registration is done settings->setValue("registered", true); settings->sync(); if (!settings->isWritable()){ setError("Configuration is not writable, device registration failed."); return false; } emit registrationStatusChanged(); return true; }
bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) { boost::shared_ptr<PKCS12Certificate> pkcs12Certificate = boost::dynamic_pointer_cast<PKCS12Certificate>(certificate); if (!pkcs12Certificate || pkcs12Certificate->isNull()) { return false; } // Create a PKCS12 structure BIO* bio = BIO_new(BIO_s_mem()); BIO_write(bio, vecptr(pkcs12Certificate->getData()), pkcs12Certificate->getData().size()); boost::shared_ptr<PKCS12> pkcs12(d2i_PKCS12_bio(bio, NULL), PKCS12_free); BIO_free(bio); if (!pkcs12) { return false; } // Parse PKCS12 X509 *certPtr = 0; EVP_PKEY* privateKeyPtr = 0; STACK_OF(X509)* caCertsPtr = 0; int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr); if (result != 1) { return false; } boost::shared_ptr<X509> cert(certPtr, X509_free); boost::shared_ptr<EVP_PKEY> privateKey(privateKeyPtr, EVP_PKEY_free); boost::shared_ptr<STACK_OF(X509)> caCerts(caCertsPtr, freeX509Stack); // Use the key & certificates if (SSL_CTX_use_certificate(context_, cert.get()) != 1) { return false; } if (SSL_CTX_use_PrivateKey(context_, privateKey.get()) != 1) { return false; } for (int i = 0; i < sk_X509_num(caCerts.get()); ++i) { SSL_CTX_add_extra_chain_cert(context_, sk_X509_value(caCerts.get(), i)); } return true; }
nsresult Generate() { nsresult rv; // Get the key slot for generation later UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); if (!slot) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Remove existing certs with this name (if any) rv = RemoveExisting(); if (NS_FAILED(rv)) { return rv; } // Generate a new cert NS_NAMED_LITERAL_CSTRING(commonNamePrefix, "CN="); nsAutoCString subjectNameStr(commonNamePrefix + mNickname); UniqueCERTName subjectName(CERT_AsciiToName(subjectNameStr.get())); if (!subjectName) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Use the well-known NIST P-256 curve SECOidData* curveOidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); if (!curveOidData) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Get key params from the curve ScopedAutoSECItem keyParams(2 + curveOidData->oid.len); keyParams.data[0] = SEC_ASN1_OBJECT_ID; keyParams.data[1] = curveOidData->oid.len; memcpy(keyParams.data + 2, curveOidData->oid.data, curveOidData->oid.len); // Generate cert key pair SECKEYPublicKey* tempPublicKey; UniqueSECKEYPrivateKey privateKey( PK11_GenerateKeyPair(slot.get(), CKM_EC_KEY_PAIR_GEN, &keyParams, &tempPublicKey, true /* token */, true /* sensitive */, nullptr)); UniqueSECKEYPublicKey publicKey(tempPublicKey); tempPublicKey = nullptr; if (!privateKey || !publicKey) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Create subject public key info and cert request UniqueCERTSubjectPublicKeyInfo spki( SECKEY_CreateSubjectPublicKeyInfo(publicKey.get())); if (!spki) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } UniqueCERTCertificateRequest certRequest( CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr)); if (!certRequest) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Valid from one day before to 1 year after static const PRTime oneDay = PRTime(PR_USEC_PER_SEC) * PRTime(60) // sec * PRTime(60) // min * PRTime(24); // hours PRTime now = PR_Now(); PRTime notBefore = now - oneDay; PRTime notAfter = now + (PRTime(365) * oneDay); UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter)); if (!validity) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Generate random serial unsigned long serial; // This serial in principle could collide, but it's unlikely rv = MapSECStatus(PK11_GenerateRandomOnSlot( slot.get(), BitwiseCast<unsigned char*, unsigned long*>(&serial), sizeof(serial))); if (NS_FAILED(rv)) { return rv; } // Create the cert from these pieces UniqueCERTCertificate cert( CERT_CreateCertificate(serial, subjectName.get(), validity.get(), certRequest.get())); if (!cert) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Update the cert version to X509v3 if (!cert->version.data) { return NS_ERROR_INVALID_POINTER; } *(cert->version.data) = SEC_CERTIFICATE_VERSION_3; cert->version.len = 1; // Set cert signature algorithm PLArenaPool* arena = cert->arena; if (!arena) { return NS_ERROR_INVALID_POINTER; } rv = MapSECStatus( SECOID_SetAlgorithmID(arena, &cert->signature, SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0)); if (NS_FAILED(rv)) { return rv; } // Encode and self-sign the cert UniqueSECItem certDER( SEC_ASN1EncodeItem(nullptr, nullptr, cert.get(), SEC_ASN1_GET(CERT_CertificateTemplate))); if (!certDER) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } rv = MapSECStatus( SEC_DerSignData(arena, &cert->derCert, certDER->data, certDER->len, privateKey.get(), SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE)); if (NS_FAILED(rv)) { return rv; } // Create a CERTCertificate from the signed data UniqueCERTCertificate certFromDER( CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &cert->derCert, nullptr, true /* perm */, true /* copyDER */)); if (!certFromDER) { return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); } // Save the cert in the DB rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER.get(), CK_INVALID_HANDLE, mNickname.get(), false /* unused */)); if (NS_FAILED(rv)) { return rv; } // We should now have cert in the DB, read it back in nsIX509Cert form return GetFromDB(); }
void Ssu::updateCredentials(bool force){ SsuCoreConfig *settings = SsuCoreConfig::instance(); errorFlag = false; SsuLog *ssuLog = SsuLog::instance(); if (deviceInfo.deviceUid() == ""){ setError("No valid UID available for your device. For phones: is your modem online?"); return; } QString ssuCaCertificate, ssuCredentialsUrl; if (!settings->contains("ca-certificate")){ setError("CA certificate for SSU not set (config key 'ca-certificate')"); return; } else ssuCaCertificate = settings->value("ca-certificate").toString(); if (!settings->contains("credentials-url")){ ssuCredentialsUrl = repoUrl("credentials-url"); if (ssuCredentialsUrl.isEmpty()){ setError("URL for credentials update not set (config key 'credentials-url')"); return; } } else ssuCredentialsUrl = settings->value("credentials-url").toString(); if (!isRegistered()){ setError("Device is not registered."); return; } if (!force){ // skip updating if the last update was less than 30 minutes ago QDateTime now = QDateTime::currentDateTime(); if (settings->contains("lastCredentialsUpdate")){ QDateTime last = settings->value("lastCredentialsUpdate").toDateTime(); if (last >= now.addSecs(-1800)){ ssuLog->print(LOG_DEBUG, QString("Skipping credentials update, last update was at %1") .arg(last.toString())); emit done(); return; } } } // check when the last update was, decide if an update is required QSslConfiguration sslConfiguration; if (!useSslVerify()) sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); QSslKey privateKey(settings->value("privateKey").toByteArray(), QSsl::Rsa); QSslCertificate certificate(settings->value("certificate").toByteArray()); QList<QSslCertificate> caCertificates; caCertificates << QSslCertificate::fromPath(ssuCaCertificate); sslConfiguration.setCaCertificates(caCertificates); sslConfiguration.setPrivateKey(privateKey); sslConfiguration.setLocalCertificate(certificate); QNetworkRequest request; request.setUrl(QUrl(ssuCredentialsUrl.arg(deviceInfo.deviceUid()))); ssuLog->print(LOG_DEBUG, QString("Sending credential update request to %1") .arg(request.url().toString())); request.setSslConfiguration(sslConfiguration); pendingRequests++; manager->get(request); }