selfSignedServerCert_SHA1_RSA_2048: add error handling.

This adds much needed error handling to the
selfSignedServerCert_SHA1_RSA_2048() function.

This covers thorough checking of return values for calls
into OpenSSL API, as well as strict null checking on values
that one would expect to be non-null.

Better safe than sorry.
This commit is contained in:
Mikkel Krautz 2017-05-07 21:48:34 +02:00
parent 3210091774
commit 70da3baeca

View File

@ -35,43 +35,130 @@ static bool selfSignedServerCert_SHA1_RSA_2048(QSslCertificate &qscCert, QSslKey
ASN1_TIME *notAfter = NULL;
unsigned char *commonName = NULL;
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
if (CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) == -1) {
ok = false;
goto out;
}
x509 = X509_new();
pkey = EVP_PKEY_new();
rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL);
EVP_PKEY_assign_RSA(pkey, rsa);
if (x509 == NULL) {
ok = false;
goto out;
}
X509_set_version(x509, 2);
pkey = EVP_PKEY_new();
if (pkey == NULL) {
ok = false;
goto out;
}
rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL);
if (rsa == NULL) {
ok = false;
goto out;
}
if (EVP_PKEY_assign_RSA(pkey, rsa) == 0) {
ok = false;
goto out;
}
if (X509_set_version(x509, 2) == 0) {
ok = false;
goto out;
}
serialNumber = X509_get_serialNumber(x509);
ASN1_INTEGER_set(serialNumber, 1);
if (serialNumber == NULL) {
ok = false;
goto out;
}
if (ASN1_INTEGER_set(serialNumber, 1) == 0) {
ok = false;
goto out;
}
notBefore = X509_get_notBefore(x509);
X509_gmtime_adj(notBefore, 0);
if (notBefore == NULL) {
ok = false;
goto out;
}
if (X509_gmtime_adj(notBefore, 0) == NULL) {
ok = false;
goto out;
}
notAfter = X509_get_notAfter(x509);
X509_gmtime_adj(notAfter, 60*60*24*365*20);
if (notAfter == NULL) {
ok = false;
goto out;
}
if (X509_gmtime_adj(notAfter, 60*60*24*365*20) == NULL) {
ok = false;
goto out;
}
X509_set_pubkey(x509, pkey);
if (X509_set_pubkey(x509, pkey) == 0) {
ok = false;
goto out;
}
name = X509_get_subject_name(x509);
if (name == NULL) {
ok = false;
goto out;
}
commonName = reinterpret_cast<unsigned char *>(const_cast<char *>("Murmur Autogenerated Certificate v2"));
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, commonName, -1, -1, 0);
X509_set_issuer_name(x509, name);
add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE"));
add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth"));
add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash"));
add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur"));
if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, commonName, -1, -1, 0) == 0) {
ok = false;
goto out;
}
X509_sign(x509, pkey, EVP_sha1());
if (X509_set_issuer_name(x509, name) == 0) {
ok = false;
goto out;
}
if (add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")) == 0) {
ok = false;
goto out;
}
if (add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")) == 0) {
ok = false;
goto out;
}
if (add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")) == 0) {
ok = false;
goto out;
}
if (add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")) == 0) {
ok = false;
goto out;
}
if (X509_sign(x509, pkey, EVP_sha1()) == 0) {
ok = false;
goto out;
}
{
QByteArray crt;
crt.resize(i2d_X509(x509, NULL));
int len = i2d_X509(x509, NULL);
if (len <= 0) {
ok = false;
goto out;
}
crt.resize(len);
unsigned char *dptr = reinterpret_cast<unsigned char *>(crt.data());
i2d_X509(x509, &dptr);
if (i2d_X509(x509, &dptr) != len) {
ok = false;
goto out;
}
qscCert = QSslCertificate(crt, QSsl::Der);
if (qscCert.isNull()) {
@ -81,9 +168,18 @@ static bool selfSignedServerCert_SHA1_RSA_2048(QSslCertificate &qscCert, QSslKey
{
QByteArray key;
key.resize(i2d_PrivateKey(pkey, NULL));
int len = i2d_PrivateKey(pkey, NULL);
if (len <= 0) {
ok = false;
goto out;
}
key.resize(len);
unsigned char *dptr = reinterpret_cast<unsigned char *>(key.data());
i2d_PrivateKey(pkey, &dptr);
if (i2d_PrivateKey(pkey, &dptr) != len) {
ok = false;
goto out;
}
qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);
if (qskKey.isNull()) {
@ -91,6 +187,18 @@ static bool selfSignedServerCert_SHA1_RSA_2048(QSslCertificate &qscCert, QSslKey
}
}
out:
// We only need to free the pkey pointer,
// not the RSA pointer. We have assigned
// our RSA key to pkey, and it will be freed
// once we free pkey.
if (pkey) {
EVP_PKEY_free(pkey);
}
if (x509) {
X509_free(x509);
}
if (!ok) {
qscCert = QSslCertificate();
qskKey = QSslKey();