mirror of
https://github.com/openssl/openssl.git
synced 2026-05-07 20:12:39 +00:00
ce22d29f5f
X509_verify is documented to return -1 if the algorithm is invalid or can't be compared for any reason. Sadly this implies that it is legitimate to pass it an incorrect X509 object and it should see this. If we hand it a new X509 object with nothing filled in, it will memcmp(NULL...) at the end of a stack of FOO_cmp abstractions, which is UB. Fix this by permitting the 0 length case to return equal without a memcmp, as suggested by slontis@ and botovq@ Fixes: https://github.com/openssl/openssl/issues/30922 Reviewed-by: Tomas Mraz <tomas@openssl.foundation> Reviewed-by: Matt Caswell <matt@openssl.foundation> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org> Reviewed-by: Neil Horman <nhorman@openssl.org> MergeDate: Wed May 6 14:55:20 2026 (Merged from https://github.com/openssl/openssl/pull/30943)
66 lines
1.7 KiB
C
66 lines
1.7 KiB
C
/*
|
|
* Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "internal/cryptlib.h"
|
|
#include <openssl/objects.h>
|
|
#include <openssl/buffer.h>
|
|
#include "crypto/asn1.h"
|
|
#include "crypto/asn1/asn1_local.h"
|
|
|
|
ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
|
|
{
|
|
ASN1_OBJECT *r;
|
|
|
|
if (o == NULL)
|
|
return NULL;
|
|
/* If object isn't dynamic it's an internal OID which is never freed */
|
|
if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
|
|
return (ASN1_OBJECT *)o;
|
|
|
|
r = ossl_asn1_object_new();
|
|
if (r == NULL) {
|
|
ERR_raise(ERR_LIB_OBJ, ERR_R_ASN1_LIB);
|
|
return NULL;
|
|
}
|
|
|
|
/* Set dynamic flags so everything gets freed up on error */
|
|
|
|
r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA);
|
|
|
|
if (o->length > 0 && (r->data = OPENSSL_memdup(o->data, o->length)) == NULL)
|
|
goto err;
|
|
|
|
r->length = o->length;
|
|
r->nid = o->nid;
|
|
|
|
if (o->ln != NULL && (r->ln = OPENSSL_strdup(o->ln)) == NULL)
|
|
goto err;
|
|
|
|
if (o->sn != NULL && (r->sn = OPENSSL_strdup(o->sn)) == NULL)
|
|
goto err;
|
|
|
|
return r;
|
|
err:
|
|
ASN1_OBJECT_free(r);
|
|
return NULL;
|
|
}
|
|
|
|
int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
|
|
{
|
|
int ret;
|
|
|
|
ret = (a->length - b->length);
|
|
if (ret)
|
|
return ret;
|
|
if (a->length == 0)
|
|
return 0;
|
|
return memcmp(a->data, b->data, a->length);
|
|
}
|