Update key generation in ykcs11 to work with OpenSSL 1.1

Manually setting a signature for a certificate is not possible in
OpenSSL 1.1 because some of the structs have become opaque. Use
X509_sign() with a bogus key instead.
This commit is contained in:
Alessio Di Mauro
2018-05-03 10:16:42 +02:00
parent 0bae4b53ce
commit 15aef8957d
+26 -17
View File
@@ -75,6 +75,8 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa,
RSA *rsa = NULL; RSA *rsa = NULL;
BIGNUM *bignum_n = NULL; BIGNUM *bignum_n = NULL;
BIGNUM *bignum_e = NULL; BIGNUM *bignum_e = NULL;
BIGNUM *bignum_prv = NULL;
unsigned char zeroes[512] = {0};
EC_KEY *eck = NULL; EC_KEY *eck = NULL;
EC_GROUP *ecg = NULL; EC_GROUP *ecg = NULL;
EC_POINT *ecp = NULL; EC_POINT *ecp = NULL;
@@ -115,13 +117,20 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa,
if(*data_ptr != 0x82) if(*data_ptr != 0x82)
goto create_empty_cert_cleanup; goto create_empty_cert_cleanup;
// OpenSSL 1.1 doesn't allow to set empty signatures
// Use a bogus private key
bignum_prv = BN_bin2bn(zeroes, len, NULL);
if (bignum_prv == NULL)
goto create_empty_cert_cleanup;
data_ptr++; data_ptr++;
data_ptr += get_length(data_ptr, &len); data_ptr += get_length(data_ptr, &len);
bignum_e = BN_bin2bn(data_ptr, len, NULL); bignum_e = BN_bin2bn(data_ptr, len, NULL);
if(bignum_e == NULL) if(bignum_e == NULL)
goto create_empty_cert_cleanup; goto create_empty_cert_cleanup;
RSA_set0_key(rsa, bignum_n, bignum_e, NULL); if (RSA_set0_key(rsa, bignum_n, bignum_e, bignum_prv) == 0)
goto create_empty_cert_cleanup;
if (EVP_PKEY_set1_RSA(key, rsa) == 0) if (EVP_PKEY_set1_RSA(key, rsa) == 0)
goto create_empty_cert_cleanup; goto create_empty_cert_cleanup;
@@ -155,6 +164,15 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa,
if (EC_KEY_set_public_key(eck, ecp) == 0) if (EC_KEY_set_public_key(eck, ecp) == 0)
goto create_empty_cert_cleanup; goto create_empty_cert_cleanup;
// OpenSSL 1.1 doesn't allow to set empty signatures
// Use a bogus private key
bignum_prv = BN_bin2bn(zeroes, 65, NULL);
if (bignum_prv == NULL)
goto create_empty_cert_cleanup;
if (EC_KEY_set_private_key(eck, bignum_prv) == 0)
goto create_empty_cert_cleanup;
if (EVP_PKEY_set1_EC_KEY(key, eck) == 0) if (EVP_PKEY_set1_EC_KEY(key, eck) == 0)
goto create_empty_cert_cleanup; goto create_empty_cert_cleanup;
} }
@@ -170,18 +188,9 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa,
X509_set_notBefore(cert, tm); X509_set_notBefore(cert, tm);
X509_set_notAfter(cert, tm); X509_set_notAfter(cert, tm);
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) // Write a bogus signature to make a valid certificate
// Manually set the signature algorithms. if (X509_sign(cert, key, EVP_sha1()) == 0)
// OpenSSL 1.0.1i complains about empty DER fields goto create_empty_cert_cleanup;
// 8 => md5WithRsaEncryption
cert->sig_alg->algorithm = OBJ_nid2obj(8);
cert->cert_info->signature->algorithm = OBJ_nid2obj(8);
// Manually set a signature (same reason as before)
ASN1_BIT_STRING_set_bit(cert->signature, 8, 1);
ASN1_BIT_STRING_set(cert->signature, (unsigned char*)"\x00", 1);
ASN1_BIT_STRING_set(cert->signature, (unsigned char*)"\x00", 1);
#endif
len = i2d_X509(cert, NULL); len = i2d_X509(cert, NULL);
if (len < 0) if (len < 0)
@@ -223,10 +232,10 @@ create_empty_cert_cleanup:
bignum_e = NULL; bignum_e = NULL;
} }
/* if (rsa != NULL) { // TODO: adding this generates an error. Automatically free'd by EVP_PKEY_free ? if (bignum_prv != NULL) {
RSA_free(rsa); BN_free(bignum_prv);
rsa = NULL; bignum_prv = NULL;
}*/ }
if (ecp != NULL) { if (ecp != NULL) {
EC_POINT_free(ecp); EC_POINT_free(ecp);