Update OpenSSL API usage to support OpenSSL 1.1

Most structure definitions in OpenSSL are now opaque and we must call
the appropriate accessor functions to get information from them.
Not all the accessors are available in older versions, so define the
missing accessors as macros.

The X509_retrieve_match() function is no longer usable, as we cannot
initialise an X509_OBJECT ourselves.  Instead, iterate over the
certificate store and use X509_OBJECT_get_type and X509_cmp to
compare certificates.
This commit is contained in:
Ben Hutchings 2016-06-26 22:04:29 +02:00 committed by James Bottomley
parent 73a261f238
commit 79d0c44afb
2 changed files with 41 additions and 18 deletions

View file

@ -203,16 +203,15 @@ static int x509_key_parse(struct key *key, uint8_t *data, size_t len)
return -1; return -1;
/* we use the X509 serial number as the key ID */ /* we use the X509 serial number as the key ID */
if (!x509->cert_info || !x509->cert_info->serialNumber) serial = X509_get_serialNumber(x509);
if (!serial)
goto out; goto out;
serial = x509->cert_info->serialNumber;
key->id_len = ASN1_STRING_length(serial); key->id_len = ASN1_STRING_length(serial);
key->id = talloc_memdup(key, ASN1_STRING_data(serial), key->id_len); key->id = talloc_memdup(key, ASN1_STRING_data(serial), key->id_len);
key->description = talloc_array(key, char, description_len); key->description = talloc_array(key, char, description_len);
X509_NAME_oneline(x509->cert_info->subject, X509_NAME_oneline(X509_get_subject_name(x509),
key->description, description_len); key->description, description_len);
rc = 0; rc = 0;

View file

@ -56,6 +56,14 @@
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_OBJECT_get0_X509(obj) ((obj)->data.x509)
#define X509_OBJECT_get_type(obj) ((obj)->type)
#define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
#define X509_STORE_get0_objects(certs) ((certs)->objs)
#define X509_get_extended_key_usage(cert) ((cert)->ex_xkusage)
#endif
static const char *toolname = "sbverify"; static const char *toolname = "sbverify";
static const int cert_name_len = 160; static const int cert_name_len = 160;
@ -124,9 +132,9 @@ static void print_signature_info(PKCS7 *p7)
for (i = 0; i < sk_X509_num(p7->d.sign->cert); i++) { for (i = 0; i < sk_X509_num(p7->d.sign->cert); i++) {
cert = sk_X509_value(p7->d.sign->cert, i); cert = sk_X509_value(p7->d.sign->cert, i);
X509_NAME_oneline(cert->cert_info->subject, X509_NAME_oneline(X509_get_subject_name(cert),
subject_name, cert_name_len); subject_name, cert_name_len);
X509_NAME_oneline(cert->cert_info->issuer, X509_NAME_oneline(X509_get_issuer_name(cert),
issuer_name, cert_name_len); issuer_name, cert_name_len);
printf(" - subject: %s\n", subject_name); printf(" - subject: %s\n", subject_name);
@ -137,20 +145,26 @@ static void print_signature_info(PKCS7 *p7)
static void print_certificate_store_certs(X509_STORE *certs) static void print_certificate_store_certs(X509_STORE *certs)
{ {
char subject_name[cert_name_len + 1], issuer_name[cert_name_len + 1]; char subject_name[cert_name_len + 1], issuer_name[cert_name_len + 1];
STACK_OF(X509_OBJECT) *objs;
X509_OBJECT *obj; X509_OBJECT *obj;
X509 *cert;
int i; int i;
printf("certificate store:\n"); printf("certificate store:\n");
for (i = 0; i < sk_X509_OBJECT_num(certs->objs); i++) { objs = X509_STORE_get0_objects(certs);
obj = sk_X509_OBJECT_value(certs->objs, i);
if (obj->type != X509_LU_X509) for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
obj = sk_X509_OBJECT_value(objs, i);
if (X509_OBJECT_get_type(obj) != X509_LU_X509)
continue; continue;
X509_NAME_oneline(obj->data.x509->cert_info->subject, cert = X509_OBJECT_get0_X509(obj);
X509_NAME_oneline(X509_get_subject_name(cert),
subject_name, cert_name_len); subject_name, cert_name_len);
X509_NAME_oneline(obj->data.x509->cert_info->issuer, X509_NAME_oneline(X509_get_issuer_name(cert),
issuer_name, cert_name_len); issuer_name, cert_name_len);
printf(" - subject: %s\n", subject_name); printf(" - subject: %s\n", subject_name);
@ -166,12 +180,21 @@ static int load_detached_signature_data(struct image *image,
static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx) static int cert_in_store(X509 *cert, X509_STORE_CTX *ctx)
{ {
X509_OBJECT obj; STACK_OF(X509_OBJECT) *objs;
X509_OBJECT *obj;
int i;
obj.type = X509_LU_X509; objs = X509_STORE_get0_objects(X509_STORE_CTX_get0_store(ctx));
obj.data.x509 = cert;
return X509_OBJECT_retrieve_match(ctx->ctx->objs, &obj) != NULL; for (i = 0; i < sk_X509_OBJECT_num(objs); i++) {
obj = sk_X509_OBJECT_value(objs, i);
if (X509_OBJECT_get_type(obj) == X509_LU_X509 &&
!X509_cmp(X509_OBJECT_get0_X509(obj), cert))
return 1;
}
return 0;
} }
static int x509_verify_cb(int status, X509_STORE_CTX *ctx) static int x509_verify_cb(int status, X509_STORE_CTX *ctx)
@ -179,8 +202,9 @@ static int x509_verify_cb(int status, X509_STORE_CTX *ctx)
int err = X509_STORE_CTX_get_error(ctx); int err = X509_STORE_CTX_get_error(ctx);
/* also accept code-signing keys */ /* also accept code-signing keys */
if (err == X509_V_ERR_INVALID_PURPOSE if (err == X509_V_ERR_INVALID_PURPOSE &&
&& ctx->cert->ex_xkusage == XKU_CODE_SIGN) X509_get_extended_key_usage(X509_STORE_CTX_get0_cert(ctx))
== XKU_CODE_SIGN)
status = 1; status = 1;
else if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY || else if (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
@ -189,7 +213,7 @@ static int x509_verify_cb(int status, X509_STORE_CTX *ctx)
err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) { err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE) {
/* all certs given with the --cert argument are trusted */ /* all certs given with the --cert argument are trusted */
if (cert_in_store(ctx->current_cert, ctx)) if (cert_in_store(X509_STORE_CTX_get_current_cert(ctx), ctx))
status = 1; status = 1;
} else if (err == X509_V_ERR_CERT_HAS_EXPIRED || } else if (err == X509_V_ERR_CERT_HAS_EXPIRED ||
err == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD || err == X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD ||