/* * Copyright 2004 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
#include"rtc_base/openssl_key_pair.h"
#include <memory> #include <utility>
#include"absl/strings/string_view.h"
#ifdefined(WEBRTC_WIN) // Must be included first before openssl headers. #include"rtc_base/win32.h"// NOLINT #endif// WEBRTC_WIN
// We could have exposed a myriad of parameters for the crypto stuff, // but keeping it simple seems best.
// Generate a key pair. Caller is responsible for freeing the returned object. static EVP_PKEY* MakeKey(const KeyParams& key_params) {
RTC_LOG(LS_INFO) << "Making key pair";
EVP_PKEY* pkey = EVP_PKEY_new(); if (key_params.type() == KT_RSA) { int key_length = key_params.rsa_params().mod_size;
BIGNUM* exponent = BN_new();
RSA* rsa = RSA_new(); if (!pkey || !exponent || !rsa ||
!BN_set_word(exponent, key_params.rsa_params().pub_exp) ||
!RSA_generate_key_ex(rsa, key_length, exponent, nullptr) ||
!EVP_PKEY_assign_RSA(pkey, rsa)) {
EVP_PKEY_free(pkey);
BN_free(exponent);
RSA_free(rsa);
RTC_LOG(LS_ERROR) << "Failed to make RSA key pair"; return nullptr;
} // ownership of rsa struct was assigned, don't free it.
BN_free(exponent);
} elseif (key_params.type() == KT_ECDSA) { if (key_params.ec_curve() == EC_NIST_P256) {
EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (!ec_key) {
EVP_PKEY_free(pkey);
RTC_LOG(LS_ERROR) << "Failed to allocate EC key"; return nullptr;
}
// Ensure curve name is included when EC key is serialized. // Without this call, OpenSSL versions before 1.1.0 will create // certificates that don't work for TLS. // This is a no-op for BoringSSL and OpenSSL 1.1.0+
EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE);
if (!pkey || !ec_key || !EC_KEY_generate_key(ec_key) ||
!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) {
EVP_PKEY_free(pkey);
EC_KEY_free(ec_key);
RTC_LOG(LS_ERROR) << "Failed to make EC key pair"; return nullptr;
} // ownership of ec_key struct was assigned, don't free it.
} else { // Add generation of any other curves here.
EVP_PKEY_free(pkey);
RTC_LOG(LS_ERROR) << "ECDSA key requested for unknown curve"; return nullptr;
}
} else {
EVP_PKEY_free(pkey);
RTC_LOG(LS_ERROR) << "Key type requested not understood"; return nullptr;
}
std::unique_ptr<OpenSSLKeyPair> OpenSSLKeyPair::FromPrivateKeyPEMString(
absl::string_view pem_string) {
BIO* bio =
BIO_new_mem_buf(const_cast<char*>(pem_string.data()), pem_string.size()); if (!bio) {
RTC_LOG(LS_ERROR) << "Failed to create a new BIO buffer."; return nullptr;
}
BIO_set_mem_eof_return(bio, 0);
EVP_PKEY* pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
BIO_free(bio); // Frees the BIO, but not the pointed-to string. if (!pkey) {
RTC_LOG(LS_ERROR) << "Failed to create the private key from PEM string."; return nullptr;
} if (EVP_PKEY_missing_parameters(pkey) != 0) {
RTC_LOG(LS_ERROR)
<< "The resulting key pair is missing public key parameters.";
EVP_PKEY_free(pkey); return nullptr;
} return std::make_unique<OpenSSLKeyPair>(pkey);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.