Latest update.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2020 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
|
||||
@@ -145,6 +145,7 @@ static ASN1_ITEM_EXP *asn1_item_list[] = {
|
||||
#endif
|
||||
ASN1_ITEM_ref(SXNETID),
|
||||
ASN1_ITEM_ref(SXNET),
|
||||
ASN1_ITEM_ref(ISSUER_SIGN_TOOL),
|
||||
ASN1_ITEM_ref(USERNOTICE),
|
||||
ASN1_ITEM_ref(X509_ALGORS),
|
||||
ASN1_ITEM_ref(X509_ALGOR),
|
||||
|
||||
+88
-30
@@ -22,11 +22,13 @@ static int _asn1_check_infinite_end(const unsigned char **p, long len)
|
||||
/*
|
||||
* If there is 0 or 1 byte left, the length check should pick things up
|
||||
*/
|
||||
if (len <= 0)
|
||||
return 1;
|
||||
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
|
||||
(*p) += 2;
|
||||
if (len <= 0) {
|
||||
return 1;
|
||||
} else {
|
||||
if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
|
||||
(*p) += 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -45,7 +47,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
int *pclass, long omax)
|
||||
{
|
||||
int i, ret;
|
||||
long l;
|
||||
long len;
|
||||
const unsigned char *p = *pp;
|
||||
int tag, xclass, inf;
|
||||
long max = omax;
|
||||
@@ -59,18 +61,18 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
p++;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
l = 0;
|
||||
len = 0;
|
||||
while (*p & 0x80) {
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
len <<= 7L;
|
||||
len |= *(p++) & 0x7f;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
if (l > (INT_MAX >> 7L))
|
||||
if (len > (INT_MAX >> 7L))
|
||||
goto err;
|
||||
}
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
tag = (int)l;
|
||||
len <<= 7L;
|
||||
len |= *(p++) & 0x7f;
|
||||
tag = (int)len;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
} else {
|
||||
@@ -141,8 +143,9 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
|
||||
}
|
||||
if (ret > LONG_MAX)
|
||||
return 0;
|
||||
} else
|
||||
} else {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
*pp = p;
|
||||
*rl = (long)ret;
|
||||
@@ -160,9 +163,9 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
||||
|
||||
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
|
||||
i |= (xclass & V_ASN1_PRIVATE);
|
||||
if (tag < 31)
|
||||
if (tag < 31) {
|
||||
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
|
||||
else {
|
||||
} else {
|
||||
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
|
||||
for (i = 0, ttag = tag; ttag > 0; i++)
|
||||
ttag >>= 7;
|
||||
@@ -185,6 +188,7 @@ void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
||||
int ASN1_put_eoc(unsigned char **pp)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*pp = p;
|
||||
@@ -194,20 +198,21 @@ int ASN1_put_eoc(unsigned char **pp)
|
||||
static void asn1_put_length(unsigned char **pp, int length)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
int i, l;
|
||||
if (length <= 127)
|
||||
int i, len;
|
||||
|
||||
if (length <= 127) {
|
||||
*(p++) = (unsigned char)length;
|
||||
else {
|
||||
l = length;
|
||||
for (i = 0; l > 0; i++)
|
||||
l >>= 8;
|
||||
} else {
|
||||
len = length;
|
||||
for (i = 0; len > 0; i++)
|
||||
len >>= 8;
|
||||
*(p++) = i | 0x80;
|
||||
l = i;
|
||||
len = i;
|
||||
while (i-- > 0) {
|
||||
p[i] = length & 0xff;
|
||||
length >>= 8;
|
||||
}
|
||||
p += l;
|
||||
p += len;
|
||||
}
|
||||
*pp = p;
|
||||
}
|
||||
@@ -215,6 +220,7 @@ static void asn1_put_length(unsigned char **pp, int length)
|
||||
int ASN1_object_size(int constructed, int length, int tag)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (length < 0)
|
||||
return -1;
|
||||
if (tag >= 31) {
|
||||
@@ -256,6 +262,7 @@ int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
|
||||
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
ret = ASN1_STRING_new();
|
||||
@@ -268,18 +275,29 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
|
||||
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
|
||||
{
|
||||
unsigned char *c;
|
||||
const char *data = _data;
|
||||
size_t len;
|
||||
|
||||
if (len < 0) {
|
||||
if (len_in < 0) {
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
else
|
||||
len = strlen(data);
|
||||
len = strlen(data);
|
||||
} else {
|
||||
len = (size_t)len_in;
|
||||
}
|
||||
if ((str->length <= len) || (str->data == NULL)) {
|
||||
/*
|
||||
* Verify that the length fits within an integer for assignment to
|
||||
* str->length below. The additional 1 is subtracted to allow for the
|
||||
* '\0' terminator even though this isn't strictly necessary.
|
||||
*/
|
||||
if (len > INT_MAX - 1) {
|
||||
ASN1err(0, ASN1_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
if ((size_t)str->length <= len || str->data == NULL) {
|
||||
c = str->data;
|
||||
str->data = OPENSSL_realloc(c, len + 1);
|
||||
if (str->data == NULL) {
|
||||
@@ -359,8 +377,9 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
|
||||
return a->type - b->type;
|
||||
else
|
||||
return i;
|
||||
} else
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int ASN1_STRING_length(const ASN1_STRING *x)
|
||||
@@ -383,9 +402,48 @@ const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
|
||||
return x->data;
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
#ifndef OPENSSL_NO_DEPRECATED_1_1_0
|
||||
unsigned char *ASN1_STRING_data(ASN1_STRING *x)
|
||||
{
|
||||
return x->data;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep,
|
||||
size_t max_len /* excluding NUL terminator */)
|
||||
{
|
||||
int i;
|
||||
ASN1_UTF8STRING *current;
|
||||
size_t length = 0, sep_len;
|
||||
char *result = NULL;
|
||||
char *p;
|
||||
|
||||
if (!ossl_assert(sep != NULL))
|
||||
return NULL;
|
||||
sep_len = strlen(sep);
|
||||
|
||||
for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
|
||||
current = sk_ASN1_UTF8STRING_value(text, i);
|
||||
if (i > 0)
|
||||
length += sep_len;
|
||||
length += ASN1_STRING_length(current);
|
||||
if (length > max_len)
|
||||
return NULL;
|
||||
}
|
||||
if ((result = OPENSSL_malloc(length + 1)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) {
|
||||
current = sk_ASN1_UTF8STRING_value(text, i);
|
||||
length = ASN1_STRING_length(current);
|
||||
if (i > 0 && sep_len > 0) {
|
||||
strncpy(p, sep, sep_len + 1);
|
||||
p += sep_len;
|
||||
}
|
||||
strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);
|
||||
p += length;
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -11,7 +11,15 @@ IF[{- !$disabled{asm} -}]
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
SOURCE[../../libcrypto]=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
|
||||
$ALL=bf_skey.c bf_ecb.c bf_cfb64.c bf_ofb64.c $BFASM
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# blowfish functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
ENDIF
|
||||
|
||||
GENERATE[bf-586.s]=asm/bf-586.pl
|
||||
DEPEND[bf-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "bio_local.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -51,6 +52,17 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
|
||||
BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
{
|
||||
/*
|
||||
* The new socket is created successfully regardless of ktls_enable.
|
||||
* ktls_enable doesn't change any functionality of the socket, except
|
||||
* changing the setsockopt to enable the processing of ktls_start.
|
||||
* Thus, it is not a problem to call it for non-TLS sockets.
|
||||
*/
|
||||
ktls_enable(sock);
|
||||
}
|
||||
# endif
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ int BIO_set_ex_data(BIO *bio, int idx, void *data)
|
||||
return CRYPTO_set_ex_data(&(bio->ex_data), idx, data);
|
||||
}
|
||||
|
||||
void *BIO_get_ex_data(BIO *bio, int idx)
|
||||
void *BIO_get_ex_data(const BIO *bio, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&(bio->ex_data), idx);
|
||||
}
|
||||
|
||||
@@ -222,19 +222,20 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
|
||||
break;
|
||||
|
||||
case ACPT_S_CREATE_SOCKET:
|
||||
ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
BIO_ADDRINFO_socktype(c->addr_iter),
|
||||
BIO_ADDRINFO_protocol(c->addr_iter), 0);
|
||||
if (ret == (int)INVALID_SOCKET) {
|
||||
s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
|
||||
BIO_ADDRINFO_socktype(c->addr_iter),
|
||||
BIO_ADDRINFO_protocol(c->addr_iter), 0);
|
||||
if (s == (int)INVALID_SOCKET) {
|
||||
ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
|
||||
"calling socket(%s, %s)",
|
||||
c->param_addr, c->param_serv);
|
||||
BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
|
||||
goto exit_loop;
|
||||
}
|
||||
c->accept_sock = ret;
|
||||
b->num = ret;
|
||||
c->accept_sock = s;
|
||||
b->num = s;
|
||||
c->state = ACPT_S_LISTEN;
|
||||
s = -1;
|
||||
break;
|
||||
|
||||
case ACPT_S_LISTEN:
|
||||
|
||||
+52
-2
@@ -11,6 +11,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "bio_local.h"
|
||||
#include "internal/ktls.h"
|
||||
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
@@ -20,6 +21,9 @@ typedef struct bio_connect_st {
|
||||
char *param_hostname;
|
||||
char *param_service;
|
||||
int connect_mode;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
unsigned char record_type;
|
||||
# endif
|
||||
|
||||
BIO_ADDRINFO *addr_first;
|
||||
const BIO_ADDRINFO *addr_iter;
|
||||
@@ -308,7 +312,12 @@ static int conn_read(BIO *b, char *out, int outl)
|
||||
|
||||
if (out != NULL) {
|
||||
clear_socket_error();
|
||||
ret = readsocket(b->num, out, outl);
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
if (BIO_get_ktls_recv(b))
|
||||
ret = ktls_read_record(b->num, out, outl);
|
||||
else
|
||||
# endif
|
||||
ret = readsocket(b->num, out, outl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0) {
|
||||
if (BIO_sock_should_retry(ret))
|
||||
@@ -333,7 +342,16 @@ static int conn_write(BIO *b, const char *in, int inl)
|
||||
}
|
||||
|
||||
clear_socket_error();
|
||||
ret = writesocket(b->num, in, inl);
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
if (BIO_should_ktls_ctrl_msg_flag(b)) {
|
||||
ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
|
||||
if (ret >= 0) {
|
||||
ret = inl;
|
||||
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||
}
|
||||
} else
|
||||
# endif
|
||||
ret = writesocket(b->num, in, inl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0) {
|
||||
if (BIO_sock_should_retry(ret))
|
||||
@@ -349,6 +367,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
const char **pptr = NULL;
|
||||
long ret = 1;
|
||||
BIO_CONNECT *data;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
# ifdef __FreeBSD__
|
||||
struct tls_enable *crypto_info;
|
||||
# else
|
||||
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
|
||||
# endif
|
||||
# endif
|
||||
|
||||
data = (BIO_CONNECT *)b->ptr;
|
||||
|
||||
@@ -497,6 +522,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
case BIO_CTRL_EOF:
|
||||
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
|
||||
break;
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
case BIO_CTRL_SET_KTLS:
|
||||
# ifdef __FreeBSD__
|
||||
crypto_info = (struct tls_enable *)ptr;
|
||||
# else
|
||||
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
|
||||
# endif
|
||||
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
|
||||
if (ret)
|
||||
BIO_set_ktls_flag(b, num);
|
||||
break;
|
||||
case BIO_CTRL_GET_KTLS_SEND:
|
||||
return BIO_should_ktls_flag(b, 1);
|
||||
case BIO_CTRL_GET_KTLS_RECV:
|
||||
return BIO_should_ktls_flag(b, 0);
|
||||
case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
|
||||
BIO_set_ktls_ctrl_msg_flag(b);
|
||||
data->record_type = num;
|
||||
ret = 0;
|
||||
break;
|
||||
case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
|
||||
BIO_clear_ktls_ctrl_msg_flag(b);
|
||||
ret = 0;
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
+4
-1
@@ -70,7 +70,8 @@ SOURCE[../providers/libfips.a]=$CORE_COMMON
|
||||
$UTIL_COMMON=\
|
||||
cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
|
||||
ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
|
||||
context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM
|
||||
context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \
|
||||
param_build_set.c der_writer.c
|
||||
$UTIL_DEFINE=$CPUIDDEF
|
||||
|
||||
SOURCE[../libcrypto]=$UTIL_COMMON \
|
||||
@@ -79,6 +80,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
|
||||
o_fopen.c getenv.c o_init.c o_fips.c init.c trace.c provider.c \
|
||||
$UPLINKSRC
|
||||
SOURCE[../providers/libfips.a]=$UTIL_COMMON
|
||||
SOURCE[../providers/liblegacy.a]=$UTIL_COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
# need to be applied to all affected libraries and modules.
|
||||
@@ -86,6 +88,7 @@ DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF
|
||||
DEFINE[../providers/libfips.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/fips]=$UTIL_DEFINE
|
||||
DEFINE[../providers/libimplementations.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/liblegacy.a]=$UTIL_DEFINE
|
||||
DEFINE[../providers/libcommon.a]=$UTIL_DEFINE
|
||||
|
||||
DEPEND[info.o]=buildinf.h
|
||||
|
||||
@@ -12,7 +12,15 @@ IF[{- !$disabled{asm} && !$disabled{pic} -}]
|
||||
ENDIF
|
||||
ENDIF
|
||||
|
||||
SOURCE[../../libcrypto]=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
|
||||
$ALL=c_skey.c c_ecb.c $CASTASM c_cfb64.c c_ofb64.c
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# cast functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
ENDIF
|
||||
|
||||
GENERATE[cast-586.s]=asm/cast-586.pl
|
||||
DEPEND[cast-586.s]=../perlasm/x86asm.pl ../perlasm/cbc.pl
|
||||
@@ -1,3 +1,4 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c
|
||||
cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \
|
||||
cmp_server.c cmp_client.c cmp_http.c
|
||||
@@ -0,0 +1,881 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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 "cmp_local.h"
|
||||
#include "internal/cryptlib.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "openssl/cmp_util.h"
|
||||
|
||||
#define IS_CREP(t) ((t) == OSSL_CMP_PKIBODY_IP || (t) == OSSL_CMP_PKIBODY_CP \
|
||||
|| (t) == OSSL_CMP_PKIBODY_KUP)
|
||||
|
||||
/*-
|
||||
* Evaluate whether there's an exception (violating the standard) configured for
|
||||
* handling negative responses without protection or with invalid protection.
|
||||
* Returns 1 on acceptance, 0 on rejection, or -1 on (internal) error.
|
||||
*/
|
||||
static int unprotected_exception(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *rep,
|
||||
int invalid_protection,
|
||||
int expected_type /* ignored here */)
|
||||
{
|
||||
int rcvd_type = ossl_cmp_msg_get_bodytype(rep /* may be NULL */);
|
||||
const char *msg_type = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && rep != NULL))
|
||||
return -1;
|
||||
|
||||
if (!ctx->unprotectedErrors)
|
||||
return 0;
|
||||
|
||||
switch (rcvd_type) {
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
msg_type = "error response";
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_RP:
|
||||
{
|
||||
OSSL_CMP_PKISI *si =
|
||||
ossl_cmp_revrepcontent_get_pkisi(rep->body->value.rp,
|
||||
OSSL_CMP_REVREQSID);
|
||||
|
||||
if (si == NULL)
|
||||
return -1;
|
||||
if (ossl_cmp_pkisi_get_status(si) == OSSL_CMP_PKISTATUS_rejection)
|
||||
msg_type = "revocation response message with rejection status";
|
||||
break;
|
||||
}
|
||||
case OSSL_CMP_PKIBODY_PKICONF:
|
||||
msg_type = "PKI Confirmation message";
|
||||
break;
|
||||
default:
|
||||
if (IS_CREP(rcvd_type)) {
|
||||
OSSL_CMP_CERTREPMESSAGE *crepmsg = rep->body->value.ip;
|
||||
OSSL_CMP_CERTRESPONSE *crep =
|
||||
ossl_cmp_certrepmessage_get0_certresponse(crepmsg,
|
||||
-1 /* any rid */);
|
||||
|
||||
if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1)
|
||||
return -1;
|
||||
/* TODO: handle potentially multiple CertResponses in CertRepMsg */
|
||||
if (crep == NULL)
|
||||
return -1;
|
||||
if (ossl_cmp_pkisi_get_status(crep->status)
|
||||
== OSSL_CMP_PKISTATUS_rejection)
|
||||
msg_type = "CertRepMessage with rejection status";
|
||||
}
|
||||
}
|
||||
if (msg_type == NULL)
|
||||
return 0;
|
||||
ossl_cmp_log2(WARN, ctx, "ignoring %s protection of %s",
|
||||
invalid_protection ? "invalid" : "missing", msg_type);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Save error info from PKIStatusInfo field of a certresponse into ctx */
|
||||
static int save_statusInfo(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_PKIFREETEXT *ss;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && si != NULL))
|
||||
return 0;
|
||||
|
||||
if ((ctx->status = ossl_cmp_pkisi_get_status(si)) < 0)
|
||||
return 0;
|
||||
|
||||
ctx->failInfoCode = 0;
|
||||
if (si->failInfo != NULL) {
|
||||
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++) {
|
||||
if (ASN1_BIT_STRING_get_bit(si->failInfo, i))
|
||||
ctx->failInfoCode |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ossl_cmp_ctx_set0_statusString(ctx, sk_ASN1_UTF8STRING_new_null())
|
||||
|| (ctx->statusString == NULL))
|
||||
return 0;
|
||||
|
||||
ss = si->statusString; /* may be NULL */
|
||||
for (i = 0; i < sk_ASN1_UTF8STRING_num(ss); i++) {
|
||||
ASN1_UTF8STRING *str = sk_ASN1_UTF8STRING_value(ss, i);
|
||||
|
||||
if (!sk_ASN1_UTF8STRING_push(ctx->statusString, ASN1_STRING_dup(str)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Perform the generic aspects of sending a request and receiving a response.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *rep.
|
||||
* Returns 0 on error.
|
||||
* Regardless of success, caller is responsible for freeing *rep (unless NULL).
|
||||
*/
|
||||
static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req,
|
||||
OSSL_CMP_MSG **rep, int expected_type)
|
||||
{
|
||||
const char *req_type_str =
|
||||
ossl_cmp_bodytype_to_string(ossl_cmp_msg_get_bodytype(req));
|
||||
const char *expected_type_str = ossl_cmp_bodytype_to_string(expected_type);
|
||||
int msg_timeout;
|
||||
int bt;
|
||||
time_t now = time(NULL);
|
||||
int time_left;
|
||||
OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb;
|
||||
|
||||
if (transfer_cb == NULL)
|
||||
transfer_cb = OSSL_CMP_MSG_http_perform;
|
||||
|
||||
*rep = NULL;
|
||||
msg_timeout = ctx->msg_timeout; /* backup original value */
|
||||
if ((IS_CREP(expected_type) || expected_type == OSSL_CMP_PKIBODY_POLLREP)
|
||||
&& ctx->total_timeout > 0 /* timeout is not infinite */) {
|
||||
if (now >= ctx->end_time) {
|
||||
CMPerr(0, CMP_R_TOTAL_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
if (!ossl_assert(ctx->end_time - time(NULL) < INT_MAX)) {
|
||||
/* cannot really happen due to the assignment in do_certreq_seq() */
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
time_left = (int)(ctx->end_time - now);
|
||||
if (ctx->msg_timeout == 0 || time_left < ctx->msg_timeout)
|
||||
ctx->msg_timeout = time_left;
|
||||
}
|
||||
|
||||
/* should print error queue since transfer_cb may call ERR_clear_error() */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
ossl_cmp_log1(INFO, ctx, "sending %s", req_type_str);
|
||||
|
||||
*rep = (*transfer_cb)(ctx, req);
|
||||
ctx->msg_timeout = msg_timeout; /* restore original value */
|
||||
|
||||
if (*rep == NULL) {
|
||||
CMPerr(0, CMP_R_TRANSFER_ERROR); /* or receiving response */
|
||||
ERR_add_error_data(1, req_type_str);
|
||||
ERR_add_error_data(2, ", expected response: ", expected_type_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bt = ossl_cmp_msg_get_bodytype(*rep);
|
||||
/*
|
||||
* The body type in the 'bt' variable is not yet verified.
|
||||
* Still we use this preliminary value already for a progress report because
|
||||
* the following msg verification may also produce log entries and may fail.
|
||||
*/
|
||||
ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt));
|
||||
|
||||
if ((bt = ossl_cmp_msg_check_received(ctx, *rep, unprotected_exception,
|
||||
expected_type)) < 0)
|
||||
return 0;
|
||||
|
||||
if (bt == expected_type
|
||||
/* as an answer to polling, there could be IP/CP/KUP: */
|
||||
|| (IS_CREP(bt) && expected_type == OSSL_CMP_PKIBODY_POLLREP))
|
||||
return 1;
|
||||
|
||||
/* received message type is not one of the expected ones (e.g., error) */
|
||||
CMPerr(0, bt == OSSL_CMP_PKIBODY_ERROR ? CMP_R_RECEIVED_ERROR :
|
||||
CMP_R_UNEXPECTED_PKIBODY); /* in next line for mkerr.pl */
|
||||
|
||||
if (bt != OSSL_CMP_PKIBODY_ERROR) {
|
||||
ERR_add_error_data(3, "message type is '",
|
||||
ossl_cmp_bodytype_to_string(bt), "'");
|
||||
} else {
|
||||
OSSL_CMP_ERRORMSGCONTENT *emc = (*rep)->body->value.error;
|
||||
OSSL_CMP_PKISI *si = emc->pKIStatusInfo;
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
|
||||
if (save_statusInfo(ctx, si)
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
if (emc->errorCode != NULL
|
||||
&& BIO_snprintf(buf, sizeof(buf), "; errorCode: %ld",
|
||||
ASN1_INTEGER_get(emc->errorCode)) > 0)
|
||||
ERR_add_error_data(1, buf);
|
||||
if (emc->errorDetails != NULL) {
|
||||
char *text = sk_ASN1_UTF8STRING2text(emc->errorDetails, ", ",
|
||||
OSSL_CMP_PKISI_BUFLEN - 1);
|
||||
|
||||
if (text != NULL)
|
||||
ERR_add_error_data(2, "; errorDetails: ", text);
|
||||
OPENSSL_free(text);
|
||||
}
|
||||
if (ctx->status != OSSL_CMP_PKISTATUS_rejection) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKISTATUS);
|
||||
if (ctx->status == OSSL_CMP_PKISTATUS_waiting)
|
||||
ctx->status = OSSL_CMP_PKISTATUS_rejection;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-
|
||||
* When a 'waiting' PKIStatus has been received, this function is used to
|
||||
* poll, which should yield a pollRep or finally a CertRepMessage in ip/cp/kup.
|
||||
* On receiving a pollRep, which includes a checkAfter value, it return this
|
||||
* value if sleep == 0, else it sleeps as long as indicated and retries.
|
||||
*
|
||||
* A transaction timeout is enabled if ctx->total_timeout is > 0.
|
||||
* In this case polling will continue until the timeout is reached and then
|
||||
* polling is done a last time even if this is before the "checkAfter" time.
|
||||
*
|
||||
* Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *rep.
|
||||
* In this case the caller is responsible for freeing *rep.
|
||||
* Returns 0 on error (which includes the case that timeout has been reached).
|
||||
*/
|
||||
static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
||||
OSSL_CMP_MSG **rep, int *checkAfter)
|
||||
{
|
||||
OSSL_CMP_MSG *preq = NULL;
|
||||
OSSL_CMP_MSG *prep = NULL;
|
||||
|
||||
ossl_cmp_info(ctx,
|
||||
"received 'waiting' PKIStatus, starting to poll for response");
|
||||
*rep = NULL;
|
||||
for (;;) {
|
||||
/* TODO: handle potentially multiple poll requests per message */
|
||||
if ((preq = ossl_cmp_pollReq_new(ctx, rid)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, preq, &prep, OSSL_CMP_PKIBODY_POLLREP))
|
||||
goto err;
|
||||
|
||||
/* handle potential pollRep */
|
||||
if (ossl_cmp_msg_get_bodytype(prep) == OSSL_CMP_PKIBODY_POLLREP) {
|
||||
OSSL_CMP_POLLREPCONTENT *prc = prep->body->value.pollRep;
|
||||
OSSL_CMP_POLLREP *pollRep = NULL;
|
||||
int64_t check_after;
|
||||
char str[OSSL_CMP_PKISI_BUFLEN];
|
||||
int len;
|
||||
|
||||
/* TODO: handle potentially multiple elements in pollRep */
|
||||
if (sk_OSSL_CMP_POLLREP_num(prc) > 1) {
|
||||
CMPerr(0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
|
||||
goto err;
|
||||
}
|
||||
pollRep = ossl_cmp_pollrepcontent_get0_pollrep(prc, rid);
|
||||
if (pollRep == NULL)
|
||||
goto err;
|
||||
|
||||
if (!ASN1_INTEGER_get_int64(&check_after, pollRep->checkAfter)) {
|
||||
CMPerr(0, CMP_R_BAD_CHECKAFTER_IN_POLLREP);
|
||||
goto err;
|
||||
}
|
||||
if (check_after < 0 || (uint64_t)check_after
|
||||
> (sleep ? ULONG_MAX / 1000 : INT_MAX)) {
|
||||
CMPerr(0, CMP_R_CHECKAFTER_OUT_OF_RANGE);
|
||||
if (BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, "value = %jd",
|
||||
check_after) >= 0)
|
||||
ERR_add_error_data(1, str);
|
||||
goto err;
|
||||
}
|
||||
if (ctx->total_timeout > 0) { /* timeout is not infinite */
|
||||
const int exp = 5; /* expected max time per msg round trip */
|
||||
int64_t time_left = (int64_t)(ctx->end_time - exp - time(NULL));
|
||||
|
||||
if (time_left <= 0) {
|
||||
CMPerr(0, CMP_R_TOTAL_TIMEOUT);
|
||||
goto err;
|
||||
}
|
||||
if (time_left < check_after)
|
||||
check_after = time_left;
|
||||
/* poll one last time just when timeout was reached */
|
||||
}
|
||||
|
||||
if (pollRep->reason == NULL
|
||||
|| (len = BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN,
|
||||
" with reason = '")) < 0) {
|
||||
*str = '\0';
|
||||
} else {
|
||||
char *text = sk_ASN1_UTF8STRING2text(pollRep->reason, ", ",
|
||||
sizeof(str) - len - 2);
|
||||
|
||||
if (text == NULL
|
||||
|| BIO_snprintf(str + len, sizeof(str) - len,
|
||||
"%s'", text) < 0)
|
||||
*str = '\0';
|
||||
OPENSSL_free(text);
|
||||
}
|
||||
ossl_cmp_log2(INFO, ctx,
|
||||
"received polling response%s; checkAfter = %ld seconds",
|
||||
str, check_after);
|
||||
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
preq = NULL;
|
||||
OSSL_CMP_MSG_free(prep);
|
||||
prep = NULL;
|
||||
if (sleep) {
|
||||
ossl_sleep((unsigned long)(1000 * check_after));
|
||||
} else {
|
||||
if (checkAfter != NULL)
|
||||
*checkAfter = (int)check_after;
|
||||
return -1; /* exits the loop */
|
||||
}
|
||||
} else {
|
||||
ossl_cmp_info(ctx, "received ip/cp/kup after polling");
|
||||
/* any other body type has been rejected by send_receive_check() */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (prep == NULL)
|
||||
goto err;
|
||||
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
*rep = prep;
|
||||
|
||||
return 1;
|
||||
err:
|
||||
OSSL_CMP_MSG_free(preq);
|
||||
OSSL_CMP_MSG_free(prep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send certConf for IR, CR or KUR sequences and check response */
|
||||
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *txt)
|
||||
{
|
||||
OSSL_CMP_MSG *certConf;
|
||||
OSSL_CMP_MSG *PKIconf = NULL;
|
||||
int res = 0;
|
||||
|
||||
/* OSSL_CMP_certConf_new() also checks if all necessary options are set */
|
||||
if ((certConf = ossl_cmp_certConf_new(ctx, fail_info, txt)) == NULL)
|
||||
goto err;
|
||||
|
||||
res = send_receive_check(ctx, certConf, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(certConf);
|
||||
OSSL_CMP_MSG_free(PKIconf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Send given error and check response */
|
||||
int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
|
||||
const char *txt, int errorCode, const char *details)
|
||||
{
|
||||
OSSL_CMP_MSG *error = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
OSSL_CMP_MSG *PKIconf = NULL;
|
||||
int res = 0;
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(status, fail_info, txt)) == NULL)
|
||||
goto err;
|
||||
/* ossl_cmp_error_new() also checks if all necessary options are set */
|
||||
if ((error = ossl_cmp_error_new(ctx, si, errorCode, details, 0)) == NULL)
|
||||
goto err;
|
||||
|
||||
res = send_receive_check(ctx, error, &PKIconf, OSSL_CMP_PKIBODY_PKICONF);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(error);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
OSSL_CMP_MSG_free(PKIconf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Retrieve a copy of the certificate, if any, from the given CertResponse.
|
||||
* Take into account PKIStatusInfo of CertResponse in ctx, report it on error.
|
||||
* Returns NULL if not found or on error.
|
||||
*/
|
||||
static X509 *get1_cert_status(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
OSSL_CMP_CERTRESPONSE *crep)
|
||||
{
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
X509 *crt = NULL;
|
||||
EVP_PKEY *privkey;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && crep != NULL))
|
||||
return NULL;
|
||||
|
||||
privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
switch (ossl_cmp_pkisi_get_status(crep->status)) {
|
||||
case OSSL_CMP_PKISTATUS_waiting:
|
||||
ossl_cmp_err(ctx,
|
||||
"received \"waiting\" status for cert when actually aiming to extract cert");
|
||||
CMPerr(0, CMP_R_ENCOUNTERED_WAITING);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_grantedWithMods:
|
||||
ossl_cmp_warn(ctx, "received \"grantedWithMods\" for certificate");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_accepted:
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
/* get all information in case of a rejection before going to error */
|
||||
case OSSL_CMP_PKISTATUS_rejection:
|
||||
ossl_cmp_err(ctx, "received \"rejection\" status rather than cert");
|
||||
CMPerr(0, CMP_R_REQUEST_REJECTED_BY_SERVER);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_revocationWarning:
|
||||
ossl_cmp_warn(ctx,
|
||||
"received \"revocationWarning\" - a revocation of the cert is imminent");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_revocationNotification:
|
||||
ossl_cmp_warn(ctx,
|
||||
"received \"revocationNotification\" - a revocation of the cert has occurred");
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
|
||||
if (bodytype != OSSL_CMP_PKIBODY_KUR) {
|
||||
CMPerr(0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING);
|
||||
goto err;
|
||||
}
|
||||
crt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
break;
|
||||
default:
|
||||
ossl_cmp_log1(ERROR, ctx,
|
||||
"received unsupported PKIStatus %d for certificate",
|
||||
ctx->status);
|
||||
CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
|
||||
goto err;
|
||||
}
|
||||
if (crt == NULL) /* according to PKIStatus, we can expect a cert */
|
||||
CMPerr(0, CMP_R_CERTIFICATE_NOT_FOUND);
|
||||
|
||||
return crt;
|
||||
|
||||
err:
|
||||
if (OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Callback fn validating that the new certificate can be verified, using
|
||||
* ctx->certConf_cb_arg, which has been initialized using opt_out_trusted, and
|
||||
* ctx->untrusted_certs, which at this point already contains ctx->extraCertsIn.
|
||||
* Returns 0 on acceptance, else a bit field reflecting PKIFailureInfo.
|
||||
* Quoting from RFC 4210 section 5.1. Overall PKI Message:
|
||||
* The extraCerts field can contain certificates that may be useful to
|
||||
* the recipient. For example, this can be used by a CA or RA to
|
||||
* present an end entity with certificates that it needs to verify its
|
||||
* own new certificate (if, for example, the CA that issued the end
|
||||
* entity's certificate is not a root CA for the end entity). Note that
|
||||
* this field does not necessarily contain a certification path; the
|
||||
* recipient may have to sort, select from, or otherwise process the
|
||||
* extra certificates in order to use them.
|
||||
* Note: While often handy, there is no hard requirement by CMP that
|
||||
* an EE must be able to validate the certificates it gets enrolled.
|
||||
*/
|
||||
int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
|
||||
const char **text)
|
||||
{
|
||||
X509_STORE *out_trusted = OSSL_CMP_CTX_get_certConf_cb_arg(ctx);
|
||||
(void)text; /* make (artificial) use of var to prevent compiler warning */
|
||||
|
||||
if (fail_info != 0) /* accept any error flagged by CMP core library */
|
||||
return fail_info;
|
||||
|
||||
if (out_trusted != NULL
|
||||
&& !OSSL_CMP_validate_cert_path(ctx, out_trusted, cert))
|
||||
fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData;
|
||||
|
||||
return fail_info;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Perform the generic handling of certificate responses for IR/CR/KUR/P10CR.
|
||||
* Returns -1 on receiving pollRep if sleep == 0, setting the checkAfter value.
|
||||
* Returns 1 on success and provides the received PKIMESSAGE in *resp.
|
||||
* Returns 0 on error (which includes the case that timeout has been reached).
|
||||
* Regardless of success, caller is responsible for freeing *resp (unless NULL).
|
||||
*/
|
||||
static int cert_response(OSSL_CMP_CTX *ctx, int sleep, int rid,
|
||||
OSSL_CMP_MSG **resp, int *checkAfter,
|
||||
int req_type, int expected_type)
|
||||
{
|
||||
EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx /* may be NULL */, 0);
|
||||
int fail_info = 0; /* no failure */
|
||||
const char *txt = NULL;
|
||||
OSSL_CMP_CERTREPMESSAGE *crepmsg;
|
||||
OSSL_CMP_CERTRESPONSE *crep;
|
||||
X509 *cert;
|
||||
char *subj = NULL;
|
||||
int ret = 1;
|
||||
|
||||
retry:
|
||||
crepmsg = (*resp)->body->value.ip; /* same for cp and kup */
|
||||
if (sk_OSSL_CMP_CERTRESPONSE_num(crepmsg->response) > 1) {
|
||||
CMPerr(0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
/* TODO: handle potentially multiple CertResponses in CertRepMsg */
|
||||
crep = ossl_cmp_certrepmessage_get0_certresponse(crepmsg, rid);
|
||||
if (crep == NULL)
|
||||
return 0;
|
||||
if (!save_statusInfo(ctx, crep->status))
|
||||
return 0;
|
||||
if (rid == -1) {
|
||||
/* for OSSL_CMP_PKIBODY_P10CR learn CertReqId from response */
|
||||
rid = ossl_cmp_asn1_get_int(crep->certReqId);
|
||||
if (rid == -1) {
|
||||
CMPerr(0, CMP_R_BAD_REQUEST_ID);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_pkisi_get_status(crep->status) == OSSL_CMP_PKISTATUS_waiting) {
|
||||
OSSL_CMP_MSG_free(*resp);
|
||||
*resp = NULL;
|
||||
if ((ret = poll_for_response(ctx, sleep, rid, resp, checkAfter)) != 0) {
|
||||
if (ret == -1) /* at this point implies sleep == 0 */
|
||||
return ret; /* waiting */
|
||||
goto retry; /* got ip/cp/kup, which may still indicate 'waiting' */
|
||||
} else {
|
||||
CMPerr(0, CMP_R_POLLING_FAILED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
cert = get1_cert_status(ctx, (*resp)->body->type, crep);
|
||||
if (cert == NULL) {
|
||||
ERR_add_error_data(1, "; cannot extract certificate from response");
|
||||
return 0;
|
||||
}
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, cert))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* if the CMP server returned certificates in the caPubs field, copy them
|
||||
* to the context so that they can be retrieved if necessary
|
||||
*/
|
||||
if (crepmsg->caPubs != NULL
|
||||
&& !ossl_cmp_ctx_set1_caPubs(ctx, crepmsg->caPubs))
|
||||
return 0;
|
||||
|
||||
/* copy received extraCerts to ctx->extraCertsIn so they can be retrieved */
|
||||
if (!ossl_cmp_ctx_set1_extraCertsIn(ctx, (*resp)->extraCerts))
|
||||
return 0;
|
||||
|
||||
subj = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
|
||||
if (rkey != NULL
|
||||
/* X509_check_private_key() also works if rkey is just public key */
|
||||
&& !(X509_check_private_key(ctx->newCert, rkey))) {
|
||||
fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_incorrectData;
|
||||
txt = "public key in new certificate does not match our enrollment key";
|
||||
/*-
|
||||
* not callling (void)ossl_cmp_exchange_error(ctx,
|
||||
* OSSL_CMP_PKISTATUS_rejection, fail_info, txt)
|
||||
* not throwing CMP_R_CERTIFICATE_NOT_ACCEPTED with txt
|
||||
* not returning 0
|
||||
* since we better leave this for any ctx->certConf_cb to decide
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the certification checking callback function possibly set in ctx,
|
||||
* which can determine whether to accept a newly enrolled certificate.
|
||||
* It may overrule the pre-decision reflected in 'fail_info' and '*txt'.
|
||||
*/
|
||||
if (ctx->certConf_cb
|
||||
&& (fail_info = ctx->certConf_cb(ctx, ctx->newCert,
|
||||
fail_info, &txt)) != 0) {
|
||||
if (txt == NULL)
|
||||
txt = "CMP client application did not accept it";
|
||||
}
|
||||
if (fail_info != 0) /* immediately log error before any certConf exchange */
|
||||
ossl_cmp_log1(ERROR, ctx,
|
||||
"rejecting newly enrolled cert with subject: %s", subj);
|
||||
|
||||
/*
|
||||
* TODO: better move certConf exchange to do_certreq_seq() such that
|
||||
* also more low-level errors with CertReqMessages get reported to server
|
||||
*/
|
||||
if (!ctx->disableConfirm
|
||||
&& !ossl_cmp_hdr_has_implicitConfirm((*resp)->header)) {
|
||||
if (!ossl_cmp_exchange_certConf(ctx, fail_info, txt))
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* not throwing failure earlier as transfer_cb may call ERR_clear_error() */
|
||||
if (fail_info != 0) {
|
||||
CMPerr(0, CMP_R_CERTIFICATE_NOT_ACCEPTED);
|
||||
ERR_add_error_data(2, "rejecting newly enrolled cert with subject: ",
|
||||
subj);
|
||||
if (txt != NULL)
|
||||
ERR_add_error_txt("; ", txt);
|
||||
ret = 0;
|
||||
}
|
||||
OPENSSL_free(subj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type, int *checkAfter)
|
||||
{
|
||||
OSSL_CMP_MSG *req = NULL;
|
||||
OSSL_CMP_MSG *rep = NULL;
|
||||
int is_p10 = req_type == OSSL_CMP_PKIBODY_P10CR;
|
||||
int rid = is_p10 ? -1 : OSSL_CMP_CERTREQID;
|
||||
int rep_type = is_p10 ? OSSL_CMP_PKIBODY_CP : req_type + 1;
|
||||
int res = 0;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->status != OSSL_CMP_PKISTATUS_waiting) { /* not polling already */
|
||||
ctx->status = -1;
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, NULL))
|
||||
return 0;
|
||||
|
||||
if (ctx->total_timeout > 0) /* else ctx->end_time is not used */
|
||||
ctx->end_time = time(NULL) + ctx->total_timeout;
|
||||
|
||||
req = ossl_cmp_certReq_new(ctx, req_type, 0 /* req_err */);
|
||||
if (req == NULL) /* also checks if all necessary options are set */
|
||||
return 0;
|
||||
|
||||
if (!send_receive_check(ctx, req, &rep, rep_type))
|
||||
goto err;
|
||||
} else {
|
||||
if (req_type < 0)
|
||||
return ossl_cmp_exchange_error(ctx, OSSL_CMP_PKISTATUS_rejection,
|
||||
0 /* TODO better fail_info value? */,
|
||||
"polling aborted", 0 /* errorCode */,
|
||||
"by application");
|
||||
res = poll_for_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter);
|
||||
if (res <= 0) /* waiting or error */
|
||||
return res;
|
||||
}
|
||||
res = cert_response(ctx, 0 /* no sleep */, rid, &rep, checkAfter,
|
||||
req_type, rep_type);
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(req);
|
||||
OSSL_CMP_MSG_free(rep);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Do the full sequence CR/IR/KUR/P10CR, CP/IP/KUP/CP,
|
||||
* certConf, PKIconf, and polling if required.
|
||||
* Will sleep as long as indicated by the server (according to checkAfter).
|
||||
* All enrollment options need to be present in the context.
|
||||
* TODO: another function to request two certificates at once should be created.
|
||||
* Returns pointer to received certificate, or NULL if none was received.
|
||||
*/
|
||||
static X509 *do_certreq_seq(OSSL_CMP_CTX *ctx, int req_type, int req_err,
|
||||
int rep_type)
|
||||
{
|
||||
OSSL_CMP_MSG *req = NULL;
|
||||
OSSL_CMP_MSG *rep = NULL;
|
||||
int rid = (req_type == OSSL_CMP_PKIBODY_P10CR) ? -1 : OSSL_CMP_CERTREQID;
|
||||
X509 *result = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
ctx->status = -1;
|
||||
if (!ossl_cmp_ctx_set0_newCert(ctx, NULL))
|
||||
return NULL;
|
||||
|
||||
if (ctx->total_timeout > 0) /* else ctx->end_time is not used */
|
||||
ctx->end_time = time(NULL) + ctx->total_timeout;
|
||||
|
||||
/* OSSL_CMP_certreq_new() also checks if all necessary options are set */
|
||||
if ((req = ossl_cmp_certReq_new(ctx, req_type, req_err)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, req, &rep, rep_type))
|
||||
goto err;
|
||||
|
||||
if (cert_response(ctx, 1 /* sleep */, rid, &rep, NULL, req_type, rep_type)
|
||||
<= 0)
|
||||
goto err;
|
||||
|
||||
result = ctx->newCert;
|
||||
err:
|
||||
OSSL_CMP_MSG_free(req);
|
||||
OSSL_CMP_MSG_free(rep);
|
||||
return result;
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_IR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_IR,
|
||||
CMP_R_ERROR_CREATING_IR, OSSL_CMP_PKIBODY_IP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_CR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_CR,
|
||||
CMP_R_ERROR_CREATING_CR, OSSL_CMP_PKIBODY_CP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_KUR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_KUR,
|
||||
CMP_R_ERROR_CREATING_KUR, OSSL_CMP_PKIBODY_KUP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_P10CR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return do_certreq_seq(ctx, OSSL_CMP_PKIBODY_P10CR,
|
||||
CMP_R_ERROR_CREATING_P10CR, OSSL_CMP_PKIBODY_CP);
|
||||
}
|
||||
|
||||
X509 *OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_MSG *rr = NULL;
|
||||
OSSL_CMP_MSG *rp = NULL;
|
||||
const int num_RevDetails = 1;
|
||||
const int rsid = OSSL_CMP_REVREQSID;
|
||||
OSSL_CMP_REVREPCONTENT *rrep = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
char buf[OSSL_CMP_PKISI_BUFLEN];
|
||||
X509 *result = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
ctx->status = -1;
|
||||
|
||||
/* OSSL_CMP_rr_new() also checks if all necessary options are set */
|
||||
if ((rr = ossl_cmp_rr_new(ctx)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!send_receive_check(ctx, rr, &rp, OSSL_CMP_PKIBODY_RP))
|
||||
goto end;
|
||||
|
||||
rrep = rp->body->value.rp;
|
||||
if (sk_OSSL_CMP_PKISI_num(rrep->status) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* evaluate PKIStatus field */
|
||||
si = ossl_cmp_revrepcontent_get_pkisi(rrep, rsid);
|
||||
if (!save_statusInfo(ctx, si))
|
||||
goto err;
|
||||
switch (ossl_cmp_pkisi_get_status(si)) {
|
||||
case OSSL_CMP_PKISTATUS_accepted:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=accepted)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_grantedWithMods:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=grantedWithMods)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_rejection:
|
||||
CMPerr(0, CMP_R_REQUEST_REJECTED_BY_SERVER);
|
||||
goto err;
|
||||
case OSSL_CMP_PKISTATUS_revocationWarning:
|
||||
ossl_cmp_info(ctx, "revocation accepted (PKIStatus=revocationWarning)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_revocationNotification:
|
||||
/* interpretation as warning or error depends on CA */
|
||||
ossl_cmp_warn(ctx,
|
||||
"revocation accepted (PKIStatus=revocationNotification)");
|
||||
result = ctx->oldCert;
|
||||
break;
|
||||
case OSSL_CMP_PKISTATUS_waiting:
|
||||
case OSSL_CMP_PKISTATUS_keyUpdateWarning:
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKISTATUS);
|
||||
goto err;
|
||||
default:
|
||||
CMPerr(0, CMP_R_UNKNOWN_PKISTATUS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* check any present CertId in optional revCerts field */
|
||||
if (rrep->revCerts != NULL) {
|
||||
OSSL_CRMF_CERTID *cid;
|
||||
OSSL_CRMF_CERTTEMPLATE *tmpl =
|
||||
sk_OSSL_CMP_REVDETAILS_value(rr->body->value.rr, rsid)->certDetails;
|
||||
const X509_NAME *issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
|
||||
ASN1_INTEGER *serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
|
||||
|
||||
if (sk_OSSL_CRMF_CERTID_num(rrep->revCerts) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if ((cid = ossl_cmp_revrepcontent_get_CertId(rrep, rsid)) == NULL) {
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (X509_NAME_cmp(issuer, OSSL_CRMF_CERTID_get0_issuer(cid)) != 0) {
|
||||
CMPerr(0, CMP_R_WRONG_CERTID_IN_RP);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
if (ASN1_INTEGER_cmp(serial,
|
||||
OSSL_CRMF_CERTID_get0_serialNumber(cid)) != 0) {
|
||||
CMPerr(0, CMP_R_WRONG_SERIAL_IN_RP);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* check number of any optionally present crls */
|
||||
if (rrep->crls != NULL && sk_X509_CRL_num(rrep->crls) != num_RevDetails) {
|
||||
CMPerr(0, CMP_R_WRONG_RP_COMPONENT_COUNT);
|
||||
result = NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err:
|
||||
if (result == NULL
|
||||
&& OSSL_CMP_CTX_snprint_PKIStatus(ctx, buf, sizeof(buf)) != NULL)
|
||||
ERR_add_error_data(1, buf);
|
||||
|
||||
end:
|
||||
OSSL_CMP_MSG_free(rr);
|
||||
OSSL_CMP_MSG_free(rp);
|
||||
return result;
|
||||
}
|
||||
|
||||
STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
OSSL_CMP_MSG *genm;
|
||||
OSSL_CMP_MSG *genp = NULL;
|
||||
STACK_OF(OSSL_CMP_ITAV) *rcvd_itavs = NULL;
|
||||
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((genm = ossl_cmp_genm_new(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!send_receive_check(ctx, genm, &genp, OSSL_CMP_PKIBODY_GENP))
|
||||
goto err;
|
||||
|
||||
/* received stack of itavs not to be freed with the genp */
|
||||
rcvd_itavs = genp->body->value.genp;
|
||||
genp->body->value.genp = NULL;
|
||||
|
||||
err:
|
||||
OSSL_CMP_MSG_free(genm);
|
||||
OSSL_CMP_MSG_free(genp);
|
||||
|
||||
return rcvd_itavs; /* recv_itavs == NULL indicates an error */
|
||||
}
|
||||
+59
-170
@@ -20,9 +20,7 @@
|
||||
#include <openssl/crmf.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*
|
||||
* Get current certificate store containing trusted root CA certs
|
||||
*/
|
||||
/* Get current certificate store containing trusted root CA certs */
|
||||
X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -36,7 +34,6 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx)
|
||||
* Set certificate store containing trusted (root) CA certs and possibly CRLs
|
||||
* and a cert verification callback function used for CMP server authentication.
|
||||
* Any already existing store entry is freed. Given NULL, the entry is reset.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
{
|
||||
@@ -49,9 +46,7 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current list of non-trusted intermediate certs
|
||||
*/
|
||||
/* Get current list of non-trusted intermediate certs */
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -64,7 +59,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set untrusted certificates for path construction in authentication of
|
||||
* the CMP server and potentially others (TLS server, newly enrolled cert).
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs)
|
||||
{
|
||||
@@ -101,9 +95,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
ctx->status = -1;
|
||||
ctx->failInfoCode = -1;
|
||||
|
||||
ctx->serverPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->proxyPort = OSSL_CMP_DEFAULT_PORT;
|
||||
ctx->msgtimeout = 2 * 60;
|
||||
ctx->msg_timeout = 2 * 60;
|
||||
|
||||
if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL)
|
||||
goto err;
|
||||
@@ -125,9 +117,7 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX
|
||||
*/
|
||||
/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */
|
||||
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -148,17 +138,16 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx)
|
||||
&& ossl_cmp_ctx_set1_recipNonce(ctx, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new()
|
||||
*/
|
||||
/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */
|
||||
void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
|
||||
OPENSSL_free(ctx->serverPath);
|
||||
OPENSSL_free(ctx->serverName);
|
||||
OPENSSL_free(ctx->proxyName);
|
||||
OPENSSL_free(ctx->server);
|
||||
OPENSSL_free(ctx->proxy);
|
||||
OPENSSL_free(ctx->no_proxy);
|
||||
|
||||
X509_free(ctx->srvCert);
|
||||
X509_free(ctx->validatedSrvCert);
|
||||
@@ -252,12 +241,8 @@ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set callback function for checking if the cert is ok or should
|
||||
* it be rejected.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_certConf_cb_t cb)
|
||||
/* Set callback function for checking if the cert is ok or should be rejected */
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -270,7 +255,6 @@ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_certConf_cb_t cb)
|
||||
/*
|
||||
* Set argument, respectively a pointer to a structure containing arguments,
|
||||
* optionally to be used by the certConf callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
@@ -380,11 +364,8 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx,
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a callback function for error reporting and logging messages.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_log_cb_t cb)
|
||||
/* Set a callback function for error reporting and logging messages */
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -411,7 +392,6 @@ void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Set or clear the reference value to be used for identification
|
||||
* (i.e., the user name) when using PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
const unsigned char *ref, int len)
|
||||
@@ -424,10 +404,7 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set or clear the password to be used for protecting messages with PBMAC.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set or clear the password to be used for protecting messages with PBMAC */
|
||||
int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
|
||||
const int len)
|
||||
{
|
||||
@@ -465,7 +442,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Copies any given stack of inbound X509 certificates to extraCertsIn
|
||||
* of the OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsIn)
|
||||
@@ -483,7 +459,6 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Duplicate and set the given stack as the new stack of X509
|
||||
* certificates to send out in the extraCerts field.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsOut)
|
||||
@@ -503,7 +478,6 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Add the given policy info object
|
||||
* to the X509_EXTENSIONS of the requested certificate template.
|
||||
* Returns 1 on success, 0 on error.
|
||||
*/
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
{
|
||||
@@ -519,9 +493,7 @@ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo)
|
||||
return sk_POLICYINFO_push(ctx->policies, pinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an ITAV for geninfo of the PKI message header
|
||||
*/
|
||||
/* Add an ITAV for geninfo of the PKI message header */
|
||||
int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -531,9 +503,7 @@ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an itav for the body of outgoing general messages
|
||||
*/
|
||||
/* Add an itav for the body of outgoing general messages */
|
||||
int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -562,7 +532,6 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Duplicate and copy the given stack of certificates to the given
|
||||
* OSSL_CMP_CTX structure so that they may be retrieved later.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs)
|
||||
{
|
||||
@@ -614,39 +583,25 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \
|
||||
* Pins the server certificate to be directly trusted (even if it is expired)
|
||||
* for verifying response messages.
|
||||
* Cert pointer is not consumed. It may be NULL to clear the entry.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509)
|
||||
|
||||
/*
|
||||
* Set the X509 name of the recipient. Set in the PKIHeader.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X509 name of the recipient. Set in the PKIHeader */
|
||||
DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME)
|
||||
|
||||
/*
|
||||
* Store the X509 name of the expected sender in the PKIHeader of responses.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Store the X509 name of the expected sender in the PKIHeader of responses */
|
||||
DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the X509 name of the issuer. Set in the PKIHeader.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X509 name of the issuer. Set in the PKIHeader */
|
||||
DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the subject name that will be placed in the certificate
|
||||
* request. This will be the subject name on the received certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME)
|
||||
|
||||
/*
|
||||
* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -680,7 +635,6 @@ int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx)
|
||||
/*
|
||||
* Add a GENERAL_NAME structure that will be added to the CRMF
|
||||
* request's extensions field to request subject alternative names.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name)
|
||||
@@ -712,7 +666,6 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
/*
|
||||
* Set our own client certificate, used for example in KUR and when
|
||||
* doing the IR with existing certificate.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(clCert, X509)
|
||||
|
||||
@@ -721,19 +674,14 @@ DEFINE_OSSL_CMP_CTX_set1_up_ref(clCert, X509)
|
||||
* or the certificate to be revoked in RR, respectively.
|
||||
* Also used as reference cert (defaulting to clCert) for deriving subject DN
|
||||
* and SANs. Its issuer is used as default recipient in the CMP message header.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509)
|
||||
|
||||
/*
|
||||
* Set the PKCS#10 CSR to be sent in P10CR.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the PKCS#10 CSR to be sent in P10CR */
|
||||
DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ)
|
||||
|
||||
/*
|
||||
* Sets the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
* Set the (newly received in IP/KUP/CP) certificate in the context.
|
||||
* TODO: this only permits for one cert to be enrolled at a time.
|
||||
*/
|
||||
int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert)
|
||||
@@ -759,16 +707,10 @@ X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->newCert;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the client's current private key.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the client's current private key */
|
||||
DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY)
|
||||
|
||||
/*
|
||||
* Set new key pair. Used e.g. when doing Key Update.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set new key pair. Used e.g. when doing Key Update */
|
||||
int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -782,9 +724,7 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* gets the private/public key to use for certificate enrollment, NULL on error
|
||||
*/
|
||||
/* Get the private/public key to use for cert enrollment, or NULL on error */
|
||||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -799,10 +739,7 @@ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv)
|
||||
return ctx->pkey; /* may be NULL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the given transactionID to the context.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the given transactionID to the context */
|
||||
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *id)
|
||||
{
|
||||
@@ -813,11 +750,7 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id);
|
||||
}
|
||||
|
||||
/*
|
||||
* sets the given nonce to be used for the recipNonce in the next message to be
|
||||
* created.
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the nonce to be used for the recipNonce in the message created next */
|
||||
int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -826,10 +759,7 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stores the given nonce as the last senderNonce sent out.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Stores the given nonce as the last senderNonce sent out */
|
||||
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce)
|
||||
{
|
||||
@@ -840,36 +770,16 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the host name of the (HTTP) proxy server to use for all connections
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxyName, char)
|
||||
/* Set the proxy server to use for HTTP(S) connections */
|
||||
DEFINE_OSSL_CMP_CTX_set1(proxy, char)
|
||||
|
||||
/*
|
||||
* Set the (HTTP) host name of the CA server.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverName, char)
|
||||
/* Set the (HTTP) host name of the CMP server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(server, char)
|
||||
|
||||
/*
|
||||
* Sets the (HTTP) proxy port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx->proxyPort = port;
|
||||
return 1;
|
||||
}
|
||||
/* Set the server exclusion list of the HTTP proxy server */
|
||||
DEFINE_OSSL_CMP_CTX_set1(no_proxy, char)
|
||||
|
||||
/*
|
||||
* sets the http connect/disconnect callback function to be used for HTTP(S)
|
||||
* returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the http connect/disconnect callback function to be used for HTTP(S) */
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -880,10 +790,7 @@ int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set argument optionally to be used by the http connect/disconnect callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set argument optionally to be used by the http connect/disconnect callback */
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -907,11 +814,8 @@ void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->http_cb_arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set callback function for sending CMP request and receiving response.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_transfer_cb_t cb)
|
||||
/* Set callback function for sending CMP request and receiving response */
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
@@ -921,10 +825,7 @@ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_cmp_transfer_cb_t cb)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set argument optionally to be used by the transfer callback.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set argument optionally to be used by the transfer callback */
|
||||
int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -948,10 +849,7 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->transfer_cb_arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the (HTTP) server port to be used.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/** Set the HTTP server port to be used */
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
@@ -962,16 +860,10 @@ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the HTTP path to be used on the server (e.g "pkix/").
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the HTTP path to be used on the server (e.g "pkix/") */
|
||||
DEFINE_OSSL_CMP_CTX_set1(serverPath, char)
|
||||
|
||||
/*
|
||||
* Set the failInfo error code as bit encoding in OSSL_CMP_CTX.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */
|
||||
int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
@@ -993,10 +885,7 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx)
|
||||
return ctx->failInfoCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets a Boolean or integer option of the context to the "val" arg.
|
||||
* Returns 1 on success, 0 on error
|
||||
*/
|
||||
/* Set a Boolean or integer option of the context to the "val" arg */
|
||||
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
{
|
||||
int min_val;
|
||||
@@ -1010,7 +899,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_REVOCATION_REASON:
|
||||
min_val = OCSP_REVOKED_STATUS_NOSTATUS;
|
||||
break;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
min_val = OSSL_CRMF_POPO_NONE;
|
||||
break;
|
||||
default:
|
||||
@@ -1030,10 +919,10 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
}
|
||||
ctx->log_verbosity = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_IMPLICITCONFIRM:
|
||||
case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
|
||||
ctx->implicitConfirm = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_DISABLECONFIRM:
|
||||
case OSSL_CMP_OPT_DISABLE_CONFIRM:
|
||||
ctx->disableConfirm = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_SEND:
|
||||
@@ -1042,7 +931,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
|
||||
ctx->unprotectedErrors = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_VALIDITYDAYS:
|
||||
case OSSL_CMP_OPT_VALIDITY_DAYS:
|
||||
ctx->days = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
|
||||
@@ -1057,7 +946,7 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
|
||||
ctx->ignore_keyusage = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
if (val > OSSL_CRMF_POPO_KEYAGREE) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
return 0;
|
||||
@@ -1073,11 +962,11 @@ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val)
|
||||
case OSSL_CMP_OPT_MAC_ALGNID:
|
||||
ctx->pbm_mac = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_MSGTIMEOUT:
|
||||
ctx->msgtimeout = val;
|
||||
case OSSL_CMP_OPT_MSG_TIMEOUT:
|
||||
ctx->msg_timeout = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_TOTALTIMEOUT:
|
||||
ctx->totaltimeout = val;
|
||||
case OSSL_CMP_OPT_TOTAL_TIMEOUT:
|
||||
ctx->total_timeout = val;
|
||||
break;
|
||||
case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
|
||||
ctx->permitTAInExtraCertsForIR = val;
|
||||
@@ -1111,15 +1000,15 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
switch (opt) {
|
||||
case OSSL_CMP_OPT_LOG_VERBOSITY:
|
||||
return ctx->log_verbosity;
|
||||
case OSSL_CMP_OPT_IMPLICITCONFIRM:
|
||||
case OSSL_CMP_OPT_IMPLICIT_CONFIRM:
|
||||
return ctx->implicitConfirm;
|
||||
case OSSL_CMP_OPT_DISABLECONFIRM:
|
||||
case OSSL_CMP_OPT_DISABLE_CONFIRM:
|
||||
return ctx->disableConfirm;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_SEND:
|
||||
return ctx->unprotectedSend;
|
||||
case OSSL_CMP_OPT_UNPROTECTED_ERRORS:
|
||||
return ctx->unprotectedErrors;
|
||||
case OSSL_CMP_OPT_VALIDITYDAYS:
|
||||
case OSSL_CMP_OPT_VALIDITY_DAYS:
|
||||
return ctx->days;
|
||||
case OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT:
|
||||
return ctx->SubjectAltName_nodefault;
|
||||
@@ -1129,7 +1018,7 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
return ctx->setPoliciesCritical;
|
||||
case OSSL_CMP_OPT_IGNORE_KEYUSAGE:
|
||||
return ctx->ignore_keyusage;
|
||||
case OSSL_CMP_OPT_POPOMETHOD:
|
||||
case OSSL_CMP_OPT_POPO_METHOD:
|
||||
return ctx->popoMethod;
|
||||
case OSSL_CMP_OPT_DIGEST_ALGNID:
|
||||
return ctx->digest;
|
||||
@@ -1137,10 +1026,10 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt)
|
||||
return ctx->pbm_owf;
|
||||
case OSSL_CMP_OPT_MAC_ALGNID:
|
||||
return ctx->pbm_mac;
|
||||
case OSSL_CMP_OPT_MSGTIMEOUT:
|
||||
return ctx->msgtimeout;
|
||||
case OSSL_CMP_OPT_TOTALTIMEOUT:
|
||||
return ctx->totaltimeout;
|
||||
case OSSL_CMP_OPT_MSG_TIMEOUT:
|
||||
return ctx->msg_timeout;
|
||||
case OSSL_CMP_OPT_TOTAL_TIMEOUT:
|
||||
return ctx->total_timeout;
|
||||
case OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR:
|
||||
return ctx->permitTAInExtraCertsForIR;
|
||||
case OSSL_CMP_OPT_REVOCATION_REASON:
|
||||
|
||||
+40
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
@@ -16,26 +16,44 @@
|
||||
static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED),
|
||||
"algorithm not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_CHECKAFTER_IN_POLLREP),
|
||||
"bad checkafter in pollrep"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_ACCEPTED),
|
||||
"certificate not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND),
|
||||
"certificate not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND),
|
||||
"certreqmsg not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND),
|
||||
"certresponse not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH),
|
||||
"cert and key do not match"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE),
|
||||
"checkafter out of range"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE),
|
||||
"checking pbm no secret available"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING),
|
||||
"encountered keyupdatewarning"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING),
|
||||
"encountered waiting"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION),
|
||||
"error calculating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF),
|
||||
"error creating certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP),
|
||||
"error creating certrep"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CR), "error creating cr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR),
|
||||
"error creating error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM),
|
||||
"error creating genm"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP),
|
||||
"error creating genp"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_IR), "error creating ir"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_KUR), "error creating kur"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_P10CR),
|
||||
"error creating p10cr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF),
|
||||
@@ -48,10 +66,14 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS),
|
||||
"error parsing pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MESSAGE),
|
||||
"error processing message"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE),
|
||||
"error protecting message"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH),
|
||||
"error setting certhash"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF),
|
||||
"error unexpected certconf"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION),
|
||||
"error validating protection"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY),
|
||||
@@ -72,6 +94,10 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"missing sender identification"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE),
|
||||
"missing trust store"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED),
|
||||
"multiple requests not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED),
|
||||
"multiple responses not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES),
|
||||
"multiple san sources"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio"},
|
||||
@@ -81,23 +107,32 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKIBODY_ERROR), "pkibody error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND),
|
||||
"pkistatusinfo not found"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POLLING_FAILED), "polling failed"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE),
|
||||
"potentially invalid certificate"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECEIVED_ERROR), "received error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECIPNONCE_UNMATCHED),
|
||||
"recipnonce unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_NOT_ACCEPTED),
|
||||
"request not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_REJECTED_BY_SERVER),
|
||||
"request rejected by server"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED),
|
||||
"sender generalname type not supported"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG),
|
||||
"srvcert does not validate msg"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TOTAL_TIMEOUT), "total timeout"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED),
|
||||
"transactionid unmatched"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS),
|
||||
"unexpected pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID),
|
||||
"unknown algorithm id"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM),
|
||||
"unsupported algorithm"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE),
|
||||
@@ -106,7 +141,11 @@ static const ERR_STRING_DATA CMP_str_reasons[] = {
|
||||
"unsupported protection alg dhbasedmac"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID),
|
||||
"wrong algorithm oid"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID_IN_RP), "wrong certid in rp"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_PBM_VALUE), "wrong pbm value"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_RP_COMPONENT_COUNT),
|
||||
"wrong rp component count"},
|
||||
{ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_SERIAL_IN_RP), "wrong serial in rp"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+27
-41
@@ -63,31 +63,42 @@ ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr)
|
||||
return hdr->recipNonce;
|
||||
}
|
||||
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name)
|
||||
{
|
||||
X509_NAME *null = X509_NAME_new();
|
||||
int res = name == NULL || null == NULL
|
||||
|| (name->type == GEN_DIRNAME
|
||||
&& X509_NAME_cmp(name->d.directoryName, null) == 0);
|
||||
|
||||
X509_NAME_free(null);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* assign to *tgt a copy of src (which may be NULL to indicate an empty DN) */
|
||||
static int set1_general_name(GENERAL_NAME **tgt, const X509_NAME *src)
|
||||
{
|
||||
GENERAL_NAME *gen;
|
||||
GENERAL_NAME *name;
|
||||
|
||||
if (!ossl_assert(tgt != NULL))
|
||||
return 0;
|
||||
if ((gen = GENERAL_NAME_new()) == NULL)
|
||||
if ((name = GENERAL_NAME_new()) == NULL)
|
||||
goto err;
|
||||
gen->type = GEN_DIRNAME;
|
||||
name->type = GEN_DIRNAME;
|
||||
|
||||
if (src == NULL) { /* NULL-DN */
|
||||
if ((gen->d.directoryName = X509_NAME_new()) == NULL)
|
||||
if ((name->d.directoryName = X509_NAME_new()) == NULL)
|
||||
goto err;
|
||||
} else if (!X509_NAME_set(&gen->d.directoryName, src)) {
|
||||
} else if (!X509_NAME_set(&name->d.directoryName, src)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
GENERAL_NAME_free(*tgt);
|
||||
*tgt = gen;
|
||||
*tgt = name;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
GENERAL_NAME_free(gen);
|
||||
GENERAL_NAME_free(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -153,25 +164,6 @@ int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
|
||||
}
|
||||
|
||||
/* push the given text string to the given PKIFREETEXT ft */
|
||||
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text)
|
||||
{
|
||||
ASN1_UTF8STRING *utf8string;
|
||||
|
||||
if (!ossl_assert(ft != NULL && text != NULL))
|
||||
return 0;
|
||||
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
|
||||
return 0;
|
||||
if (!ASN1_STRING_set(utf8string, text, -1))
|
||||
goto err;
|
||||
if (!sk_ASN1_UTF8STRING_push(ft, utf8string))
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ASN1_UTF8STRING_free(utf8string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
|
||||
{
|
||||
if (!ossl_assert(hdr != NULL && text != NULL))
|
||||
@@ -193,7 +185,8 @@ int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text)
|
||||
&& (hdr->freeText = sk_ASN1_UTF8STRING_new_null()) == NULL)
|
||||
return 0;
|
||||
|
||||
return ossl_cmp_pkifreetext_push_str(hdr->freeText, (char *)text->data);
|
||||
return
|
||||
ossl_cmp_sk_ASN1_UTF8STRING_push_str(hdr->freeText, (char *)text->data);
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
@@ -205,7 +198,7 @@ int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
}
|
||||
|
||||
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_ITAV *itav;
|
||||
@@ -250,7 +243,7 @@ int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr)
|
||||
}
|
||||
|
||||
/* return 1 if implicitConfirm in the generalInfo field of the header is set */
|
||||
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
int itavCount;
|
||||
int i;
|
||||
@@ -273,8 +266,8 @@ int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr)
|
||||
/* fill in all fields of the hdr according to the info given in ctx */
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
{
|
||||
X509_NAME *sender;
|
||||
X509_NAME *rcp = NULL;
|
||||
const X509_NAME *sender;
|
||||
const X509_NAME *rcp = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && hdr != NULL))
|
||||
return 0;
|
||||
@@ -283,19 +276,12 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr)
|
||||
if (!ossl_cmp_hdr_set_pvno(hdr, OSSL_CMP_PVNO))
|
||||
return 0;
|
||||
|
||||
sender = ctx->clCert != NULL ?
|
||||
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
|
||||
/*
|
||||
* The sender name is copied from the subject of the client cert, if any,
|
||||
* or else from the the subject name provided for certification requests.
|
||||
* As required by RFC 4210 section 5.1.1., if the sender name is not known
|
||||
* to the client it set to NULL-DN. In this case for identification at least
|
||||
* the senderKID must be set, which we take from any referenceValue given.
|
||||
* or else from the subject name provided for certification requests.
|
||||
*/
|
||||
if (sender == NULL && ctx->referenceValue == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
|
||||
return 0;
|
||||
}
|
||||
sender = ctx->clCert != NULL ?
|
||||
X509_get_subject_name(ctx->clCert) : ctx->subjectName;
|
||||
if (!ossl_cmp_hdr_set1_sender(hdr, sender))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
|
||||
#include "openssl/cmp.h"
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/*
|
||||
* Send the PKIMessage req and on success return the response, else NULL.
|
||||
* Any previous error queue entries will likely be removed by ERR_clear_error().
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
char server_port[32] = { '\0' };
|
||||
STACK_OF(CONF_VALUE) *headers = NULL;
|
||||
const char *const content_type_pkix = "application/pkixcmp";
|
||||
OSSL_CMP_MSG *res;
|
||||
|
||||
if (ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!X509V3_add_value("Pragma", "no-cache", &headers))
|
||||
return NULL;
|
||||
|
||||
if (ctx->serverPort != 0)
|
||||
BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort);
|
||||
|
||||
res = (OSSL_CMP_MSG *)
|
||||
OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath,
|
||||
OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL,
|
||||
ctx->proxy, ctx->no_proxy, NULL, NULL,
|
||||
ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx),
|
||||
headers, content_type_pkix,
|
||||
(ASN1_VALUE *)req, ASN1_ITEM_rptr(OSSL_CMP_MSG),
|
||||
0, 0, ctx->msg_timeout, content_type_pkix,
|
||||
ASN1_ITEM_rptr(OSSL_CMP_MSG));
|
||||
|
||||
sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
|
||||
return res;
|
||||
}
|
||||
+42
-49
@@ -28,20 +28,20 @@
|
||||
* this structure is used to store the context for CMP sessions
|
||||
*/
|
||||
struct ossl_cmp_ctx_st {
|
||||
OSSL_cmp_log_cb_t log_cb; /* log callback for error/debug/etc. output */
|
||||
OSSL_CMP_log_cb_t log_cb; /* log callback for error/debug/etc. output */
|
||||
OSSL_CMP_severity log_verbosity; /* level of verbosity of log output */
|
||||
|
||||
/* message transfer */
|
||||
OSSL_cmp_transfer_cb_t transfer_cb; /* default: OSSL_CMP_MSG_http_perform */
|
||||
OSSL_CMP_transfer_cb_t transfer_cb; /* default: OSSL_CMP_MSG_http_perform */
|
||||
void *transfer_cb_arg; /* allows to store optional argument to cb */
|
||||
/* HTTP-based transfer */
|
||||
char *serverPath;
|
||||
char *serverName;
|
||||
char *server;
|
||||
int serverPort;
|
||||
char *proxyName;
|
||||
int proxyPort;
|
||||
int msgtimeout; /* max seconds to wait for each CMP message round trip */
|
||||
int totaltimeout; /* maximum number seconds an enrollment may take, incl. */
|
||||
char *proxy;
|
||||
char *no_proxy;
|
||||
int msg_timeout; /* max seconds to wait for each CMP message round trip */
|
||||
int total_timeout; /* max number of seconds an enrollment may take, incl. */
|
||||
/* attempts polling for a response if a 'waiting' PKIStatus is received */
|
||||
time_t end_time; /* session start time + totaltimeout */
|
||||
OSSL_HTTP_bio_cb_t http_cb;
|
||||
@@ -56,7 +56,7 @@ struct ossl_cmp_ctx_st {
|
||||
int unprotectedErrors;
|
||||
X509 *srvCert; /* certificate used to identify the server */
|
||||
X509 *validatedSrvCert; /* caches any already validated server cert */
|
||||
X509_NAME *expected_sender; /* expected sender in pkiheader of response */
|
||||
X509_NAME *expected_sender; /* expected sender in header of response */
|
||||
X509_STORE *trusted; /* trust store maybe w CRLs and cert verify callback */
|
||||
STACK_OF(X509) *untrusted_certs; /* untrusted (intermediate) certs */
|
||||
int ignore_keyusage; /* ignore key usage entry when validating certs */
|
||||
@@ -95,7 +95,7 @@ struct ossl_cmp_ctx_st {
|
||||
int newPkey_priv; /* flag indicating if newPkey contains private key */
|
||||
X509_NAME *issuer; /* issuer name to used in cert template */
|
||||
int days; /* Number of days new certificates are asked to be valid for */
|
||||
X509_NAME *subjectName; /* subject name to be used in the cert template */
|
||||
X509_NAME *subjectName; /* subject name to be used in cert template */
|
||||
STACK_OF(GENERAL_NAME) *subjectAltNames; /* to add to the cert template */
|
||||
int SubjectAltName_nodefault;
|
||||
int setSubjectAltNameCritical;
|
||||
@@ -122,7 +122,7 @@ struct ossl_cmp_ctx_st {
|
||||
STACK_OF(X509) *extraCertsIn; /* extraCerts received from server */
|
||||
|
||||
/* certificate confirmation */
|
||||
OSSL_cmp_certConf_cb_t certConf_cb; /* callback for app checking new cert */
|
||||
OSSL_CMP_certConf_cb_t certConf_cb; /* callback for app checking new cert */
|
||||
void *certConf_cb_arg; /* allows to store an argument individual to cb */
|
||||
} /* OSSL_CMP_CTX */;
|
||||
|
||||
@@ -246,7 +246,6 @@ struct ossl_cmp_itav_st {
|
||||
} infoValue;
|
||||
} /* OSSL_CMP_ITAV */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_ITAV)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
|
||||
|
||||
typedef struct ossl_cmp_certorenccert_st {
|
||||
int type;
|
||||
@@ -284,8 +283,6 @@ struct ossl_cmp_pkisi_st {
|
||||
OSSL_CMP_PKIFREETEXT *statusString;
|
||||
OSSL_CMP_PKIFAILUREINFO *failInfo;
|
||||
} /* OSSL_CMP_PKISI */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
|
||||
/*-
|
||||
@@ -296,10 +293,11 @@ DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
* crlEntryDetails Extensions OPTIONAL
|
||||
* }
|
||||
*/
|
||||
typedef struct ossl_cmp_revdetails_st {
|
||||
struct ossl_cmp_revdetails_st {
|
||||
OSSL_CRMF_CERTTEMPLATE *certDetails;
|
||||
X509_EXTENSIONS *crlEntryDetails;
|
||||
} OSSL_CMP_REVDETAILS;
|
||||
} /* OSSL_CMP_REVDETAILS */;
|
||||
typedef struct ossl_cmp_revdetails_st OSSL_CMP_REVDETAILS;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_REVDETAILS)
|
||||
DEFINE_STACK_OF(OSSL_CMP_REVDETAILS)
|
||||
|
||||
@@ -375,7 +373,6 @@ struct ossl_cmp_certstatus_st {
|
||||
OSSL_CMP_PKISI *statusInfo;
|
||||
} /* OSSL_CMP_CERTSTATUS */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTSTATUS)
|
||||
|
||||
typedef STACK_OF(OSSL_CMP_CERTSTATUS) OSSL_CMP_CERTCONFIRMCONTENT;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_CERTCONFIRMCONTENT)
|
||||
|
||||
@@ -670,7 +667,6 @@ struct ossl_cmp_msg_st {
|
||||
STACK_OF(X509) *extraCerts; /* 1 */
|
||||
} /* OSSL_CMP_MSG */;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_MSG)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
|
||||
|
||||
/*-
|
||||
* ProtectedPart ::= SEQUENCE {
|
||||
@@ -728,17 +724,6 @@ DECLARE_ASN1_FUNCTIONS(CMP_PROTECTEDPART)
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* constants
|
||||
*/
|
||||
/* certReqId for the first - and so far only - certificate request */
|
||||
# define OSSL_CMP_CERTREQID 0
|
||||
/* sequence id for the first - and so far only - revocation request */
|
||||
# define OSSL_CMP_REVREQSID 0
|
||||
/*
|
||||
* functions
|
||||
*/
|
||||
|
||||
/* from cmp_asn.c */
|
||||
int ossl_cmp_asn1_get_int(const ASN1_INTEGER *a);
|
||||
|
||||
@@ -755,6 +740,9 @@ int ossl_cmp_sk_X509_add1_certs(STACK_OF(X509) *sk, STACK_OF(X509) *certs,
|
||||
int no_self_issued, int no_dups, int prepend);
|
||||
int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs,
|
||||
int only_self_issued);
|
||||
STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store);
|
||||
int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
|
||||
const char *text);
|
||||
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
|
||||
const ASN1_OCTET_STRING *src);
|
||||
int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt,
|
||||
@@ -800,32 +788,30 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce);
|
||||
|
||||
/* from cmp_status.c */
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_statusinfo_new(int status, int fail_info, const char *text);
|
||||
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *statusInfo);
|
||||
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si);
|
||||
const char *ossl_cmp_PKIStatus_to_string(int status);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si);
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si);
|
||||
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si);
|
||||
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index);
|
||||
int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index);
|
||||
|
||||
/* from cmp_hdr.c */
|
||||
int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno);
|
||||
int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name);
|
||||
int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
int ossl_cmp_hdr_set1_recipient(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm);
|
||||
int ossl_cmp_hdr_update_messageTime(OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_set1_senderKID(OSSL_CMP_PKIHEADER *hdr,
|
||||
const ASN1_OCTET_STRING *senderKID);
|
||||
int ossl_cmp_pkifreetext_push_str(OSSL_CMP_PKIFREETEXT *ft, const char *text);
|
||||
int ossl_cmp_hdr_push0_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
|
||||
int ossl_cmp_hdr_push1_freeText(OSSL_CMP_PKIHEADER *hdr, ASN1_UTF8STRING *text);
|
||||
int ossl_cmp_hdr_generalInfo_push0_item(OSSL_CMP_PKIHEADER *hdr,
|
||||
OSSL_CMP_ITAV *itav);
|
||||
int ossl_cmp_hdr_generalInfo_push1_items(OSSL_CMP_PKIHEADER *hdr,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
int ossl_cmp_hdr_set_implicitConfirm(OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_check_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
|
||||
int ossl_cmp_hdr_has_implicitConfirm(const OSSL_CMP_PKIHEADER *hdr);
|
||||
# define OSSL_CMP_TRANSACTIONID_LENGTH 16
|
||||
# define OSSL_CMP_SENDERNONCE_LENGTH 16
|
||||
int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
@@ -860,6 +846,10 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr);
|
||||
# define OSSL_CMP_PKIBODY_POLLREQ 25
|
||||
# define OSSL_CMP_PKIBODY_POLLREP 26
|
||||
# define OSSL_CMP_PKIBODY_TYPE_MAX OSSL_CMP_PKIBODY_POLLREP
|
||||
/* certReqId for the first - and so far only - certificate request */
|
||||
# define OSSL_CMP_CERTREQID 0
|
||||
/* sequence id for the first - and so far only - revocation request */
|
||||
# define OSSL_CMP_REVREQSID 0
|
||||
const char *ossl_cmp_bodytype_to_string(int type);
|
||||
int ossl_cmp_msg_set_bodytype(OSSL_CMP_MSG *msg, int type);
|
||||
int ossl_cmp_msg_get_bodytype(const OSSL_CMP_MSG *msg);
|
||||
@@ -875,24 +865,26 @@ OSSL_CMP_MSG *ossl_cmp_rr_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
OSSL_CRMF_CERTID *certId, int unprot_err);
|
||||
OSSL_CMP_MSG *ossl_cmp_pkiconf_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
int64_t poll_after);
|
||||
int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav);
|
||||
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs);
|
||||
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
int errorCode,
|
||||
OSSL_CMP_PKIFREETEXT *errorDetails,
|
||||
int unprotected);
|
||||
int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
const X509 *cert);
|
||||
const char *details, int unprotected);
|
||||
int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
ASN1_OCTET_STRING *hash);
|
||||
OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *text);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollReq_new(OSSL_CMP_CTX *ctx, int crid);
|
||||
OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
int64_t poll_after);
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
|
||||
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid);
|
||||
OSSL_CRMF_CERTID *ossl_cmp_revrepcontent_get_CertId(OSSL_CMP_REVREPCONTENT *rrep,
|
||||
int rsid);
|
||||
OSSL_CMP_POLLREP *
|
||||
@@ -904,11 +896,6 @@ ossl_cmp_certrepmessage_get0_certresponse(const OSSL_CMP_CERTREPMESSAGE *crepmsg
|
||||
X509 *ossl_cmp_certresponse_get1_certificate(EVP_PKEY *privkey,
|
||||
const OSSL_CMP_CERTRESPONSE *crep);
|
||||
OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file);
|
||||
/* BIO definitions */
|
||||
# define OSSL_d2i_CMP_MSG_bio(bp, p) \
|
||||
ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new, d2i_OSSL_CMP_MSG, bp, p)
|
||||
# define OSSL_i2d_CMP_MSG_bio(bp, o) \
|
||||
ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bp, o)
|
||||
|
||||
/* from cmp_protect.c */
|
||||
ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg,
|
||||
@@ -925,4 +912,10 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
ossl_cmp_allow_unprotected_cb_t cb, int cb_arg);
|
||||
int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified);
|
||||
|
||||
#endif /* !defined OSSL_CRYPTO_CMP_LOCAL_H */
|
||||
/* from cmp_client.c */
|
||||
int ossl_cmp_exchange_certConf(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
const char *txt);
|
||||
int ossl_cmp_exchange_error(OSSL_CMP_CTX *ctx, int status, int fail_info,
|
||||
const char *txt, int errorCode, const char *details);
|
||||
|
||||
#endif /* !defined(OSSL_CRYPTO_CMP_LOCAL_H) */
|
||||
+70
-72
@@ -185,8 +185,8 @@ OSSL_CMP_MSG *ossl_cmp_msg_create(OSSL_CMP_CTX *ctx, int bodytype)
|
||||
(sk_GENERAL_NAME_num((ctx)->subjectAltNames) > 0 \
|
||||
|| OSSL_CMP_CTX_reqExtensions_have_SAN(ctx) == 1)
|
||||
|
||||
static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
int bodytype)
|
||||
static const X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
int bodytype)
|
||||
{
|
||||
if (ctx->subjectName != NULL)
|
||||
return ctx->subjectName;
|
||||
@@ -205,18 +205,20 @@ static X509_NAME *determine_subj(OSSL_CMP_CTX *ctx, X509 *refcert,
|
||||
* Create CRMF certificate request message for IR/CR/KUR
|
||||
* returns a pointer to the OSSL_CRMF_MSG on success, NULL on error
|
||||
*/
|
||||
static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
int rid, EVP_PKEY *rkey)
|
||||
static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid)
|
||||
{
|
||||
OSSL_CRMF_MSG *crm = NULL;
|
||||
X509 *refcert = ctx->oldCert != NULL ? ctx->oldCert : ctx->clCert;
|
||||
/* refcert defaults to current client cert */
|
||||
EVP_PKEY *rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
|
||||
STACK_OF(GENERAL_NAME) *default_sans = NULL;
|
||||
X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
|
||||
const X509_NAME *subject = determine_subj(ctx, refcert, bodytype);
|
||||
int crit = ctx->setSubjectAltNameCritical || subject == NULL;
|
||||
/* RFC5280: subjectAltName MUST be critical if subject is null */
|
||||
X509_EXTENSIONS *exts = NULL;
|
||||
|
||||
if (rkey == NULL)
|
||||
rkey = ctx->pkey; /* default is independent of ctx->oldClCert */
|
||||
if (rkey == NULL
|
||||
|| (bodytype == OSSL_CMP_PKIBODY_KUR && refcert == NULL)) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
@@ -300,19 +302,12 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
{
|
||||
EVP_PKEY *rkey;
|
||||
EVP_PKEY *privkey;
|
||||
OSSL_CMP_MSG *msg;
|
||||
OSSL_CRMF_MSG *crm = NULL;
|
||||
|
||||
if (!ossl_assert(ctx != NULL))
|
||||
return NULL;
|
||||
|
||||
rkey = OSSL_CMP_CTX_get0_newPkey(ctx, 0);
|
||||
if (rkey == NULL)
|
||||
return NULL;
|
||||
privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
|
||||
if (type != OSSL_CMP_PKIBODY_IR && type != OSSL_CMP_PKIBODY_CR
|
||||
&& type != OSSL_CMP_PKIBODY_KUR && type != OSSL_CMP_PKIBODY_P10CR) {
|
||||
CMPerr(0, CMP_R_INVALID_ARGS);
|
||||
@@ -329,15 +324,19 @@ OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
/* body */
|
||||
/* For P10CR the content has already been set in OSSL_CMP_MSG_create */
|
||||
if (type != OSSL_CMP_PKIBODY_P10CR) {
|
||||
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
|
||||
if (privkey == NULL)
|
||||
privkey = ctx->pkey; /* default is independent of ctx->oldCert */
|
||||
if (ctx->popoMethod == OSSL_CRMF_POPO_SIGNATURE && privkey == NULL) {
|
||||
CMPerr(0, CMP_R_MISSING_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID, rkey)) == NULL
|
||||
|| !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
|
||||
ctx->popoMethod)
|
||||
/* value.ir is same for cr and kur */
|
||||
|| !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
|
||||
if ((crm = crm_new(ctx, type, OSSL_CMP_CERTREQID)) == NULL
|
||||
|| !OSSL_CRMF_MSG_create_popo(crm, privkey, ctx->digest,
|
||||
ctx->popoMethod)
|
||||
/* value.ir is same for cr and kur */
|
||||
|| !sk_OSSL_CRMF_MSG_push(msg->body->value.ir, crm))
|
||||
goto err;
|
||||
crm = NULL;
|
||||
/* TODO: here optional 2nd certreqmsg could be pushed to the stack */
|
||||
@@ -349,7 +348,8 @@ OSSL_CMP_MSG *ossl_cmp_certReq_new(OSSL_CMP_CTX *ctx, int type, int err_code)
|
||||
return msg;
|
||||
|
||||
err:
|
||||
CMPerr(0, err_code);
|
||||
if (err_code != 0)
|
||||
CMPerr(0, err_code);
|
||||
OSSL_CRMF_MSG_free(crm);
|
||||
OSSL_CMP_MSG_free(msg);
|
||||
return NULL;
|
||||
@@ -385,7 +385,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
|| !ASN1_INTEGER_set(resp->certReqId, certReqId))
|
||||
goto err;
|
||||
|
||||
status = ossl_cmp_pkisi_get_pkistatus(resp->status);
|
||||
status = ossl_cmp_pkisi_get_status(resp->status);
|
||||
if (status != OSSL_CMP_PKISTATUS_rejection
|
||||
&& status != OSSL_CMP_PKISTATUS_waiting && cert != NULL) {
|
||||
if (encrypted) {
|
||||
@@ -416,7 +416,7 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype,
|
||||
goto err;
|
||||
|
||||
if (!unprotectedErrors
|
||||
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
|
||||
@@ -511,7 +511,7 @@ OSSL_CMP_MSG *ossl_cmp_rp_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
}
|
||||
|
||||
if (!unprot_err
|
||||
|| ossl_cmp_pkisi_get_pkistatus(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
|| ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection)
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
|
||||
@@ -560,7 +560,7 @@ int ossl_cmp_msg_gen_push0_ITAV(OSSL_CMP_MSG *msg, OSSL_CMP_ITAV *itav)
|
||||
}
|
||||
|
||||
int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
int i;
|
||||
OSSL_CMP_ITAV *itav = NULL;
|
||||
@@ -583,7 +583,9 @@ int ossl_cmp_msg_gen_push1_ITAVs(OSSL_CMP_MSG *msg,
|
||||
* Creates a new General Message/Response with an empty itav stack
|
||||
* returns a pointer to the PKIMessage on success, NULL on error
|
||||
*/
|
||||
static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs,
|
||||
int body_type, int err_code)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
|
||||
@@ -594,7 +596,7 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
return NULL;
|
||||
|
||||
if (ctx->genm_ITAVs != NULL
|
||||
&& !ossl_cmp_msg_gen_push1_ITAVs(msg, ctx->genm_ITAVs))
|
||||
&& !ossl_cmp_msg_gen_push1_ITAVs(msg, itavs))
|
||||
goto err;
|
||||
|
||||
if (!ossl_cmp_msg_protect(ctx, msg))
|
||||
@@ -610,20 +612,23 @@ static OSSL_CMP_MSG *gen_new(OSSL_CMP_CTX *ctx, int body_type, int err_code)
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_genm_new(OSSL_CMP_CTX *ctx)
|
||||
{
|
||||
return gen_new(ctx, OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
|
||||
return gen_new(ctx, ctx->genm_ITAVs,
|
||||
OSSL_CMP_PKIBODY_GENM, CMP_R_ERROR_CREATING_GENM);
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx)
|
||||
OSSL_CMP_MSG *ossl_cmp_genp_new(OSSL_CMP_CTX *ctx,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *itavs)
|
||||
{
|
||||
return gen_new(ctx, OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
|
||||
return gen_new(ctx, itavs,
|
||||
OSSL_CMP_PKIBODY_GENP, CMP_R_ERROR_CREATING_GENP);
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
int errorCode,
|
||||
OSSL_CMP_PKIFREETEXT *errorDetails,
|
||||
int unprotected)
|
||||
const char *details, int unprotected)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_PKIFREETEXT *ft;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && si != NULL))
|
||||
return NULL;
|
||||
@@ -641,11 +646,13 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
if (!ASN1_INTEGER_set(msg->body->value.error->errorCode, errorCode))
|
||||
goto err;
|
||||
}
|
||||
if (errorDetails != NULL)
|
||||
if ((msg->body->value.error->errorDetails =
|
||||
sk_ASN1_UTF8STRING_deep_copy(errorDetails, ASN1_STRING_dup,
|
||||
ASN1_STRING_free)) == NULL)
|
||||
if (details != NULL) {
|
||||
if ((ft = sk_ASN1_UTF8STRING_new_null()) == NULL)
|
||||
goto err;
|
||||
msg->body->value.error->errorDetails = ft;
|
||||
if (!ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!unprotected && !ossl_cmp_msg_protect(ctx, msg))
|
||||
goto err;
|
||||
@@ -658,44 +665,18 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, OSSL_CMP_PKISI *si,
|
||||
}
|
||||
|
||||
/*
|
||||
* OSSL_CMP_CERTSTATUS_set_certHash() calculates a hash of the certificate,
|
||||
* using the same hash algorithm as is used to create and verify the
|
||||
* certificate signature, and places the hash into the certHash field of a
|
||||
* OSSL_CMP_CERTSTATUS structure. This is used in the certConf message,
|
||||
* for example, to confirm that the certificate was received successfully.
|
||||
* Set the certHash field of a OSSL_CMP_CERTSTATUS structure.
|
||||
* This is used in the certConf message, for example,
|
||||
* to confirm that the certificate was received successfully.
|
||||
*/
|
||||
int ossl_cmp_certstatus_set_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
const X509 *cert)
|
||||
int ossl_cmp_certstatus_set0_certHash(OSSL_CMP_CERTSTATUS *certStatus,
|
||||
ASN1_OCTET_STRING *hash)
|
||||
{
|
||||
unsigned int len;
|
||||
unsigned char hash[EVP_MAX_MD_SIZE];
|
||||
int md_NID;
|
||||
const EVP_MD *md = NULL;
|
||||
|
||||
if (!ossl_assert(certStatus != NULL && cert != NULL))
|
||||
if (!ossl_assert(certStatus != NULL))
|
||||
return 0;
|
||||
|
||||
/*-
|
||||
* select hash algorithm, as stated in Appendix F. Compilable ASN.1 defs:
|
||||
* the hash of the certificate, using the same hash algorithm
|
||||
* as is used to create and verify the certificate signature
|
||||
*/
|
||||
if (OBJ_find_sigid_algs(X509_get_signature_nid(cert), &md_NID, NULL)
|
||||
&& (md = EVP_get_digestbynid(md_NID)) != NULL) {
|
||||
if (!X509_digest(cert, md, hash, &len))
|
||||
goto err;
|
||||
if (!ossl_cmp_asn1_octet_string_set1_bytes(&certStatus->certHash, hash,
|
||||
len))
|
||||
goto err;
|
||||
} else {
|
||||
CMPerr(0, CMP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASN1_OCTET_STRING_free(certStatus->certHash);
|
||||
certStatus->certHash = hash;
|
||||
return 1;
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_SETTING_CERTHASH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -707,6 +688,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_CERTSTATUS *certStatus = NULL;
|
||||
ASN1_OCTET_STRING *certHash = NULL;
|
||||
OSSL_CMP_PKISI *sinfo;
|
||||
|
||||
if (!ossl_assert(ctx != NULL && ctx->newCert != NULL))
|
||||
@@ -732,8 +714,12 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
* the hash of the certificate, using the same hash algorithm
|
||||
* as is used to create and verify the certificate signature
|
||||
*/
|
||||
if (!ossl_cmp_certstatus_set_certHash(certStatus, ctx->newCert))
|
||||
if ((certHash = X509_digest_sig(ctx->newCert)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (!ossl_cmp_certstatus_set0_certHash(certStatus, certHash))
|
||||
goto err;
|
||||
certHash = NULL;
|
||||
/*
|
||||
* For any particular CertStatus, omission of the statusInfo field
|
||||
* indicates ACCEPTANCE of the specified certificate. Alternatively,
|
||||
@@ -742,8 +728,8 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
* the CA/RA.
|
||||
*/
|
||||
sinfo = fail_info != 0 ?
|
||||
ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
|
||||
ossl_cmp_statusinfo_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
|
||||
OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, fail_info, text) :
|
||||
OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_accepted, 0, text);
|
||||
if (sinfo == NULL)
|
||||
goto err;
|
||||
certStatus->statusInfo = sinfo;
|
||||
@@ -756,6 +742,7 @@ OSSL_CMP_MSG *ossl_cmp_certConf_new(OSSL_CMP_CTX *ctx, int fail_info,
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_CERTCONF);
|
||||
OSSL_CMP_MSG_free(msg);
|
||||
ASN1_OCTET_STRING_free(certHash);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -827,7 +814,7 @@ OSSL_CMP_MSG *ossl_cmp_pollRep_new(OSSL_CMP_CTX *ctx, int crid,
|
||||
* returns NULL on error
|
||||
*/
|
||||
OSSL_CMP_PKISI *
|
||||
ossl_cmp_revrepcontent_get_pkistatusinfo(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
|
||||
ossl_cmp_revrepcontent_get_pkisi(OSSL_CMP_REVREPCONTENT *rrep, int rsid)
|
||||
{
|
||||
OSSL_CMP_PKISI *status;
|
||||
|
||||
@@ -990,7 +977,18 @@ OSSL_CMP_MSG *ossl_cmp_msg_load(const char *file)
|
||||
|
||||
if ((bio = BIO_new_file(file, "rb")) == NULL)
|
||||
return NULL;
|
||||
msg = OSSL_d2i_CMP_MSG_bio(bio, NULL);
|
||||
msg = d2i_OSSL_CMP_MSG_bio(bio, NULL);
|
||||
BIO_free(bio);
|
||||
return msg;
|
||||
}
|
||||
|
||||
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg)
|
||||
{
|
||||
return ASN1_d2i_bio_of(OSSL_CMP_MSG, OSSL_CMP_MSG_new,
|
||||
d2i_OSSL_CMP_MSG, bio, msg);
|
||||
}
|
||||
|
||||
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
return ASN1_i2d_bio_of(OSSL_CMP_MSG, i2d_OSSL_CMP_MSG, bio, msg);
|
||||
}
|
||||
@@ -286,6 +286,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
* to section 5.1.1
|
||||
*/
|
||||
subjKeyIDStr = X509_get0_subject_key_id(ctx->clCert);
|
||||
if (subjKeyIDStr == NULL)
|
||||
subjKeyIDStr = ctx->referenceValue; /* fallback */
|
||||
if (subjKeyIDStr != NULL
|
||||
&& !ossl_cmp_hdr_set1_senderKID(msg->header, subjKeyIDStr))
|
||||
goto err;
|
||||
@@ -306,7 +308,18 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg)
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
/*
|
||||
* As required by RFC 4210 section 5.1.1., if the sender name is not known
|
||||
* to the client it set to NULL-DN. In this case for identification at least
|
||||
* the senderKID must be set, where we took the referenceValue as fallback.
|
||||
*/
|
||||
|
||||
if (ossl_cmp_general_name_is_NULL_DN(msg->header->sender)
|
||||
&& msg->header->senderKID == NULL)
|
||||
CMPerr(0, CMP_R_MISSING_SENDER_IDENTIFICATION);
|
||||
else
|
||||
return 1;
|
||||
|
||||
err:
|
||||
CMPerr(0, CMP_R_ERROR_PROTECTING_MESSAGE);
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
* Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* general CMP server functions */
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
#include "cmp_local.h"
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
#include <openssl/cmp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* the context for the generic CMP server */
|
||||
struct ossl_cmp_srv_ctx_st
|
||||
{
|
||||
OSSL_CMP_CTX *ctx; /* Client CMP context, partly reused for srv */
|
||||
void *custom_ctx; /* pointer to specific server context */
|
||||
|
||||
OSSL_CMP_SRV_cert_request_cb_t process_cert_request;
|
||||
OSSL_CMP_SRV_rr_cb_t process_rr;
|
||||
OSSL_CMP_SRV_genm_cb_t process_genm;
|
||||
OSSL_CMP_SRV_error_cb_t process_error;
|
||||
OSSL_CMP_SRV_certConf_cb_t process_certConf;
|
||||
OSSL_CMP_SRV_pollReq_cb_t process_pollReq;
|
||||
|
||||
int sendUnprotectedErrors; /* Send error and rejection msgs unprotected */
|
||||
int acceptUnprotected; /* Accept requests with no/invalid prot. */
|
||||
int acceptRAVerified; /* Accept ir/cr/kur with POPO RAVerified */
|
||||
int grantImplicitConfirm; /* Grant implicit confirmation if requested */
|
||||
|
||||
}; /* OSSL_CMP_SRV_CTX */
|
||||
|
||||
void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL)
|
||||
return;
|
||||
|
||||
OSSL_CMP_CTX_free(srv_ctx->ctx);
|
||||
OPENSSL_free(srv_ctx);
|
||||
}
|
||||
|
||||
OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(void)
|
||||
{
|
||||
OSSL_CMP_SRV_CTX *ctx = OPENSSL_zalloc(sizeof(OSSL_CMP_SRV_CTX));
|
||||
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
if ((ctx->ctx = OSSL_CMP_CTX_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
/* all other elements are initialized to 0 or NULL, respectively */
|
||||
return ctx;
|
||||
err:
|
||||
OSSL_CMP_SRV_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
|
||||
OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
|
||||
OSSL_CMP_SRV_rr_cb_t process_rr,
|
||||
OSSL_CMP_SRV_genm_cb_t process_genm,
|
||||
OSSL_CMP_SRV_error_cb_t process_error,
|
||||
OSSL_CMP_SRV_certConf_cb_t process_certConf,
|
||||
OSSL_CMP_SRV_pollReq_cb_t process_pollReq)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->custom_ctx = custom_ctx;
|
||||
srv_ctx->process_cert_request = process_cert_request;
|
||||
srv_ctx->process_rr = process_rr;
|
||||
srv_ctx->process_genm = process_genm;
|
||||
srv_ctx->process_error = process_error;
|
||||
srv_ctx->process_certConf = process_certConf;
|
||||
srv_ctx->process_pollReq = process_pollReq;
|
||||
return 1;
|
||||
}
|
||||
|
||||
OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
return srv_ctx->ctx;
|
||||
}
|
||||
|
||||
void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
return srv_ctx->custom_ctx;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->sendUnprotectedErrors = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->acceptUnprotected = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->acceptRAVerified = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val)
|
||||
{
|
||||
if (srv_ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
srv_ctx->grantImplicitConfirm = val != 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes an ir/cr/p10cr/kur and returns a certification response.
|
||||
* Only handles the first certification request contained in req
|
||||
* returns an ip/cp/kup on success and NULL on error
|
||||
*/
|
||||
static OSSL_CMP_MSG *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
X509 *certOut = NULL;
|
||||
STACK_OF(X509) *chainOut = NULL, *caPubs = NULL;
|
||||
const OSSL_CRMF_MSG *crm = NULL;
|
||||
const X509_REQ *p10cr = NULL;
|
||||
int bodytype;
|
||||
int certReqId;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
switch (ossl_cmp_msg_get_bodytype(req)) {
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
bodytype = OSSL_CMP_PKIBODY_CP;
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
bodytype = OSSL_CMP_PKIBODY_IP;
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
bodytype = OSSL_CMP_PKIBODY_KUP;
|
||||
break;
|
||||
default:
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_P10CR) {
|
||||
certReqId = OSSL_CMP_CERTREQID;
|
||||
p10cr = req->body->value.p10cr;
|
||||
} else {
|
||||
OSSL_CRMF_MSGS *reqs = req->body->value.ir; /* same for cr and kur */
|
||||
|
||||
if (sk_OSSL_CRMF_MSG_num(reqs) != 1) { /* TODO: handle case > 1 */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((crm = sk_OSSL_CRMF_MSG_value(reqs, OSSL_CMP_CERTREQID)) == NULL) {
|
||||
CMPerr(0, CMP_R_CERTREQMSG_NOT_FOUND);
|
||||
return NULL;
|
||||
}
|
||||
certReqId = OSSL_CRMF_MSG_get_certReqId(crm);
|
||||
}
|
||||
|
||||
if (!ossl_cmp_verify_popo(req, srv_ctx->acceptRAVerified)) {
|
||||
/* Proof of possession could not be verified */
|
||||
si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
1 << OSSL_CMP_PKIFAILUREINFO_badPOP,
|
||||
ERR_reason_error_string(ERR_peek_error()));
|
||||
if (si == NULL)
|
||||
return NULL;
|
||||
} else {
|
||||
OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(req);
|
||||
|
||||
si = srv_ctx->process_cert_request(srv_ctx, req, certReqId, crm, p10cr,
|
||||
&certOut, &chainOut, &caPubs);
|
||||
if (si == NULL)
|
||||
goto err;
|
||||
/* set OSSL_CMP_OPT_IMPLICIT_CONFIRM if and only if transaction ends */
|
||||
if (!OSSL_CMP_CTX_set_option(srv_ctx->ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM,
|
||||
ossl_cmp_hdr_has_implicitConfirm(hdr)
|
||||
&& srv_ctx->grantImplicitConfirm
|
||||
/* do not set if polling starts: */
|
||||
&& certOut != NULL))
|
||||
goto err;
|
||||
}
|
||||
|
||||
msg = ossl_cmp_certRep_new(srv_ctx->ctx, bodytype, certReqId, si,
|
||||
certOut, chainOut, caPubs, 0 /* encrypted */,
|
||||
srv_ctx->sendUnprotectedErrors);
|
||||
/*
|
||||
* TODO when implemented in ossl_cmp_certrep_new():
|
||||
* in case OSSL_CRMF_POPO_KEYENC, set encrypted
|
||||
*/
|
||||
if (msg == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_CERTREP);
|
||||
|
||||
err:
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
X509_free(certOut);
|
||||
sk_X509_pop_free(chainOut, X509_free);
|
||||
sk_X509_pop_free(caPubs, X509_free);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_rr(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_REVDETAILS *details;
|
||||
OSSL_CRMF_CERTID *certId;
|
||||
OSSL_CRMF_CERTTEMPLATE *tmpl;
|
||||
const X509_NAME *issuer;
|
||||
ASN1_INTEGER *serial;
|
||||
OSSL_CMP_PKISI *si;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
if (sk_OSSL_CMP_REVDETAILS_num(req->body->value.rr) != 1) {
|
||||
/* TODO: handle multiple elements if multiple requests have been sent */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((details = sk_OSSL_CMP_REVDETAILS_value(req->body->value.rr,
|
||||
OSSL_CMP_REVREQSID)) == NULL) {
|
||||
CMPerr(0, CMP_R_ERROR_PROCESSING_MESSAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmpl = details->certDetails;
|
||||
issuer = OSSL_CRMF_CERTTEMPLATE_get0_issuer(tmpl);
|
||||
serial = OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(tmpl);
|
||||
/* here issuer and serial may safely be NULL */
|
||||
if ((certId = OSSL_CRMF_CERTID_gen(issuer, serial)) == NULL)
|
||||
return NULL;
|
||||
if ((si = srv_ctx->process_rr(srv_ctx, req, issuer, serial)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((msg = ossl_cmp_rp_new(srv_ctx->ctx, si, certId,
|
||||
srv_ctx->sendUnprotectedErrors)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_RR);
|
||||
|
||||
err:
|
||||
OSSL_CRMF_CERTID_free(certId);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes genm and creates a genp message mirroring the contents of the
|
||||
* incoming message
|
||||
*/
|
||||
static OSSL_CMP_MSG *process_genm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_GENMSGCONTENT *itavs;
|
||||
OSSL_CMP_MSG *msg;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
if (!srv_ctx->process_genm(srv_ctx, req, req->body->value.genm, &itavs))
|
||||
return NULL;
|
||||
|
||||
msg = ossl_cmp_genp_new(srv_ctx->ctx, itavs);
|
||||
sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_error(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_ERRORMSGCONTENT *errorContent;
|
||||
OSSL_CMP_MSG *msg;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
errorContent = req->body->value.error;
|
||||
srv_ctx->process_error(srv_ctx, req, errorContent->pKIStatusInfo,
|
||||
errorContent->errorCode, errorContent->errorDetails);
|
||||
|
||||
if ((msg = ossl_cmp_pkiconf_new(srv_ctx->ctx)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_certConf(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
OSSL_CMP_CERTCONFIRMCONTENT *ccc;
|
||||
int num;
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
OSSL_CMP_CERTSTATUS *status = NULL;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
ctx = srv_ctx->ctx;
|
||||
ccc = req->body->value.certConf;
|
||||
num = sk_OSSL_CMP_CERTSTATUS_num(ccc);
|
||||
|
||||
if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 1) {
|
||||
CMPerr(0, CMP_R_ERROR_UNEXPECTED_CERTCONF);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
ossl_cmp_err(ctx, "certificate rejected by client");
|
||||
} else {
|
||||
if (num > 1)
|
||||
ossl_cmp_warn(ctx, "All CertStatus but the first will be ignored");
|
||||
status = sk_OSSL_CMP_CERTSTATUS_value(ccc, OSSL_CMP_CERTREQID);
|
||||
}
|
||||
|
||||
if (status != NULL) {
|
||||
int certReqId = ossl_cmp_asn1_get_int(status->certReqId);
|
||||
ASN1_OCTET_STRING *certHash = status->certHash;
|
||||
OSSL_CMP_PKISI *si = status->statusInfo;
|
||||
|
||||
if (!srv_ctx->process_certConf(srv_ctx, req, certReqId, certHash, si))
|
||||
return NULL; /* reason code may be: CMP_R_CERTHASH_UNMATCHED */
|
||||
|
||||
if (si != NULL && ossl_cmp_pkisi_get_status(si)
|
||||
!= OSSL_CMP_PKISTATUS_accepted) {
|
||||
int pki_status = ossl_cmp_pkisi_get_status(si);
|
||||
const char *str = ossl_cmp_PKIStatus_to_string(pki_status);
|
||||
|
||||
ossl_cmp_log2(INFO, ctx, "certificate rejected by client %s %s",
|
||||
str == NULL ? "without" : "with",
|
||||
str == NULL ? "PKIStatus" : str);
|
||||
}
|
||||
}
|
||||
|
||||
if ((msg = ossl_cmp_pkiconf_new(ctx)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_PKICONF);
|
||||
return msg;
|
||||
}
|
||||
|
||||
static OSSL_CMP_MSG *process_pollReq(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_POLLREQCONTENT *prc;
|
||||
OSSL_CMP_POLLREQ *pr;
|
||||
int certReqId;
|
||||
OSSL_CMP_MSG *certReq;
|
||||
int64_t check_after = 0;
|
||||
OSSL_CMP_MSG *msg = NULL;
|
||||
|
||||
if (!ossl_assert(srv_ctx != NULL && srv_ctx->ctx != NULL && req != NULL))
|
||||
return NULL;
|
||||
|
||||
prc = req->body->value.pollReq;
|
||||
if (sk_OSSL_CMP_POLLREQ_num(prc) != 1) { /* TODO: handle case > 1 */
|
||||
CMPerr(0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pr = sk_OSSL_CMP_POLLREQ_value(prc, 0);
|
||||
certReqId = ossl_cmp_asn1_get_int(pr->certReqId);
|
||||
if (!srv_ctx->process_pollReq(srv_ctx, req, certReqId,
|
||||
&certReq, &check_after))
|
||||
return NULL;
|
||||
|
||||
if (certReq != NULL) {
|
||||
msg = process_cert_request(srv_ctx, certReq);
|
||||
OSSL_CMP_MSG_free(certReq);
|
||||
} else {
|
||||
if ((msg = ossl_cmp_pollRep_new(srv_ctx->ctx, certReqId,
|
||||
check_after)) == NULL)
|
||||
CMPerr(0, CMP_R_ERROR_CREATING_POLLREP);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether missing/invalid protection of request message is allowed.
|
||||
* Return 1 on acceptance, 0 on rejection, or -1 on (internal) error.
|
||||
*/
|
||||
static int unprotected_exception(const OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
int invalid_protection,
|
||||
int accept_unprotected_requests)
|
||||
{
|
||||
if (!ossl_assert(ctx != NULL && req != NULL))
|
||||
return -1;
|
||||
|
||||
if (accept_unprotected_requests) {
|
||||
ossl_cmp_log1(WARN, ctx, "ignoring %s protection of request message",
|
||||
invalid_protection ? "invalid" : "missing");
|
||||
return 1;
|
||||
}
|
||||
if (ossl_cmp_msg_get_bodytype(req) == OSSL_CMP_PKIBODY_ERROR
|
||||
&& OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_UNPROTECTED_ERRORS) == 1) {
|
||||
ossl_cmp_warn(ctx, "ignoring missing protection of error message");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns created message and NULL on internal error
|
||||
*/
|
||||
OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_CTX *ctx;
|
||||
OSSL_CMP_PKIHEADER *hdr;
|
||||
int req_type, rsp_type;
|
||||
OSSL_CMP_MSG *rsp = NULL;
|
||||
|
||||
if (srv_ctx == NULL || srv_ctx->ctx == NULL
|
||||
|| req == NULL || req->body == NULL
|
||||
|| (hdr = OSSL_CMP_MSG_get0_header(req)) == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
ctx = srv_ctx->ctx;
|
||||
|
||||
if (hdr->sender->type != GEN_DIRNAME) {
|
||||
CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED);
|
||||
goto err;
|
||||
}
|
||||
if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName))
|
||||
goto err;
|
||||
|
||||
req_type = ossl_cmp_msg_get_bodytype(req);
|
||||
switch (req_type) {
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
case OSSL_CMP_PKIBODY_RR:
|
||||
case OSSL_CMP_PKIBODY_GENM:
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
if (ctx->transactionID != NULL) {
|
||||
char *tid;
|
||||
|
||||
tid = OPENSSL_buf2hexstr(ctx->transactionID->data,
|
||||
ctx->transactionID->length);
|
||||
ossl_cmp_log1(WARN, ctx,
|
||||
"Assuming that last transaction with ID=%s got aborted",
|
||||
tid);
|
||||
OPENSSL_free(tid);
|
||||
}
|
||||
/* start of a new transaction, set transactionID and senderNonce */
|
||||
if (!OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)
|
||||
|| !ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce))
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
/* transactionID should be already initialized */
|
||||
if (ctx->transactionID == NULL) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
/* ignore any (extra) error in next two function calls: */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID);
|
||||
(void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception,
|
||||
srv_ctx->acceptUnprotected) < 0)
|
||||
goto err;
|
||||
|
||||
switch (req_type) {
|
||||
case OSSL_CMP_PKIBODY_IR:
|
||||
case OSSL_CMP_PKIBODY_CR:
|
||||
case OSSL_CMP_PKIBODY_P10CR:
|
||||
case OSSL_CMP_PKIBODY_KUR:
|
||||
if (srv_ctx->process_cert_request == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_cert_request(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_RR:
|
||||
if (srv_ctx->process_rr == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_rr(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_GENM:
|
||||
if (srv_ctx->process_genm == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_genm(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
if (srv_ctx->process_error == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_error(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_CERTCONF:
|
||||
if (srv_ctx->process_certConf == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_certConf(srv_ctx, req);
|
||||
break;
|
||||
case OSSL_CMP_PKIBODY_POLLREQ:
|
||||
if (srv_ctx->process_pollReq == NULL)
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
else
|
||||
rsp = process_pollReq(srv_ctx, req);
|
||||
break;
|
||||
default:
|
||||
/* TODO possibly support further request message types */
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PKIBODY);
|
||||
}
|
||||
|
||||
err:
|
||||
if (rsp == NULL) {
|
||||
/* on error, try to respond with CMP error message to client */
|
||||
const char *data = NULL;
|
||||
int flags = 0;
|
||||
unsigned long err = ERR_peek_error_data(&data, &flags);
|
||||
int fail_info = 1 << OSSL_CMP_PKIFAILUREINFO_badRequest;
|
||||
/* TODO fail_info could be more specific */
|
||||
OSSL_CMP_PKISI *si = NULL;
|
||||
|
||||
if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection,
|
||||
fail_info, NULL)) == NULL)
|
||||
return 0;
|
||||
if (err != 0 && (flags & ERR_TXT_STRING) != 0)
|
||||
data = ERR_reason_error_string(err);
|
||||
rsp = ossl_cmp_error_new(srv_ctx->ctx, si,
|
||||
err != 0 ? ERR_GET_REASON(err) : -1,
|
||||
data, srv_ctx->sendUnprotectedErrors);
|
||||
OSSL_CMP_PKISI_free(si);
|
||||
}
|
||||
|
||||
/* possibly close the transaction */
|
||||
rsp_type =
|
||||
rsp != NULL ? ossl_cmp_msg_get_bodytype(rsp) : OSSL_CMP_PKIBODY_ERROR;
|
||||
switch (rsp_type) {
|
||||
case OSSL_CMP_PKIBODY_IP:
|
||||
case OSSL_CMP_PKIBODY_CP:
|
||||
case OSSL_CMP_PKIBODY_KUP:
|
||||
case OSSL_CMP_PKIBODY_RP:
|
||||
if (OSSL_CMP_CTX_get_option(ctx, OSSL_CMP_OPT_IMPLICIT_CONFIRM) == 0)
|
||||
break;
|
||||
/* fall through */
|
||||
|
||||
case OSSL_CMP_PKIBODY_PKICONF:
|
||||
case OSSL_CMP_PKIBODY_GENP:
|
||||
case OSSL_CMP_PKIBODY_ERROR:
|
||||
/* TODO possibly support further terminating response message types */
|
||||
(void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); /* ignore any error */
|
||||
|
||||
default: /* not closing transaction in other cases */
|
||||
break;
|
||||
}
|
||||
return rsp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Server interface that may substitute OSSL_CMP_MSG_http_perform at the client.
|
||||
* The OSSL_CMP_SRV_CTX must be set as client_ctx->transfer_cb_arg.
|
||||
* returns received message on success, else NULL and pushes an element on the
|
||||
* error stack.
|
||||
*/
|
||||
OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
|
||||
const OSSL_CMP_MSG *req)
|
||||
{
|
||||
OSSL_CMP_SRV_CTX *srv_ctx = NULL;
|
||||
|
||||
if (client_ctx == NULL || req == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((srv_ctx = OSSL_CMP_CTX_get_transfer_cb_arg(client_ctx)) == NULL) {
|
||||
CMPerr(0, CMP_R_TRANSFER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return OSSL_CMP_SRV_process_request(srv_ctx, req);
|
||||
}
|
||||
+56
-44
@@ -28,17 +28,13 @@
|
||||
|
||||
/* CMP functions related to PKIStatus */
|
||||
|
||||
int ossl_cmp_pkisi_get_pkistatus(const OSSL_CMP_PKISI *si)
|
||||
int ossl_cmp_pkisi_get_status(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
if (!ossl_assert(si != NULL && si->status != NULL))
|
||||
return -1;
|
||||
return ossl_cmp_asn1_get_int(si->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the declared identifier and a short explanation for the PKIStatus
|
||||
* value as specified in RFC4210, Appendix F.
|
||||
*/
|
||||
const char *ossl_cmp_PKIStatus_to_string(int status)
|
||||
{
|
||||
switch (status) {
|
||||
@@ -67,27 +63,19 @@ const char *ossl_cmp_PKIStatus_to_string(int status)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* returns a pointer to the statusString contained in a PKIStatusInfo
|
||||
* returns NULL on error
|
||||
*/
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusstring(const OSSL_CMP_PKISI *si)
|
||||
OSSL_CMP_PKIFREETEXT *ossl_cmp_pkisi_get0_statusString(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
if (!ossl_assert(si != NULL))
|
||||
return NULL;
|
||||
return si->statusString;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns the FailureInfo bits of the given PKIStatusInfo
|
||||
* returns -1 on error
|
||||
*/
|
||||
int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
|
||||
{
|
||||
int i;
|
||||
int res = 0;
|
||||
|
||||
if (!ossl_assert(si != NULL && si->failInfo != NULL))
|
||||
if (!ossl_assert(si != NULL))
|
||||
return -1;
|
||||
for (i = 0; i <= OSSL_CMP_PKIFAILUREINFO_MAX; i++)
|
||||
if (ASN1_BIT_STRING_get_bit(si->failInfo, i))
|
||||
@@ -95,12 +83,9 @@ int ossl_cmp_pkisi_get_pkifailureinfo(const OSSL_CMP_PKISI *si)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* internal function
|
||||
/*-
|
||||
* convert PKIFailureInfo number to human-readable string
|
||||
*
|
||||
* returns pointer to static string
|
||||
* returns NULL on error
|
||||
* returns pointer to static string, or NULL on error
|
||||
*/
|
||||
static const char *CMP_PKIFAILUREINFO_to_string(int number)
|
||||
{
|
||||
@@ -164,11 +149,7 @@ static const char *CMP_PKIFAILUREINFO_to_string(int number)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checks PKIFailureInfo bits in a given PKIStatusInfo
|
||||
* returns 1 if a given bit is set, 0 if not, -1 on error
|
||||
*/
|
||||
int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
{
|
||||
if (!ossl_assert(si != NULL && si->failInfo != NULL))
|
||||
return -1;
|
||||
@@ -180,16 +161,17 @@ int ossl_cmp_pkisi_pkifailureinfo_check(const OSSL_CMP_PKISI *si, int bit_index)
|
||||
return ASN1_BIT_STRING_get_bit(si->failInfo, bit_index);
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* place human-readable error string created from PKIStatusInfo in given buffer
|
||||
* returns pointer to the same buffer containing the string, or NULL on error
|
||||
*/
|
||||
char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
size_t bufsize)
|
||||
static
|
||||
char *snprint_PKIStatusInfo_parts(int status, int fail_info,
|
||||
const OSSL_CMP_PKIFREETEXT *status_strings,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
int status, failure, fail_info;
|
||||
int failure;
|
||||
const char *status_string, *failure_string;
|
||||
OSSL_CMP_PKIFREETEXT *status_strings;
|
||||
ASN1_UTF8STRING *text;
|
||||
int i;
|
||||
int printed_chars;
|
||||
@@ -197,22 +179,22 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
int n_status_strings;
|
||||
char *write_ptr = buf;
|
||||
|
||||
#define ADVANCE_BUFFER \
|
||||
if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
|
||||
return NULL; \
|
||||
write_ptr += printed_chars; \
|
||||
bufsize -= printed_chars;
|
||||
|
||||
if (ctx == NULL
|
||||
|| buf == NULL
|
||||
|| (status = OSSL_CMP_CTX_get_status(ctx)) < 0
|
||||
if (buf == NULL
|
||||
|| status < 0
|
||||
|| (status_string = ossl_cmp_PKIStatus_to_string(status)) == NULL)
|
||||
return NULL;
|
||||
|
||||
#define ADVANCE_BUFFER \
|
||||
if (printed_chars < 0 || (size_t)printed_chars >= bufsize) \
|
||||
return NULL; \
|
||||
write_ptr += printed_chars; \
|
||||
bufsize -= printed_chars;
|
||||
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string);
|
||||
ADVANCE_BUFFER;
|
||||
|
||||
/* failInfo is optional and may be empty */
|
||||
if ((fail_info = OSSL_CMP_CTX_get_failInfoCode(ctx)) > 0) {
|
||||
if (fail_info != 0) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: ");
|
||||
ADVANCE_BUFFER;
|
||||
for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) {
|
||||
@@ -220,7 +202,7 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
failure_string = CMP_PKIFAILUREINFO_to_string(failure);
|
||||
if (failure_string != NULL) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s",
|
||||
failure > 0 ? ", " : "",
|
||||
failinfo_found ? ", " : "",
|
||||
failure_string);
|
||||
ADVANCE_BUFFER;
|
||||
failinfo_found = 1;
|
||||
@@ -235,7 +217,6 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
}
|
||||
|
||||
/* statusString sequence is optional and may be empty */
|
||||
status_strings = OSSL_CMP_CTX_get0_statusString(ctx);
|
||||
n_status_strings = sk_ASN1_UTF8STRING_num(status_strings);
|
||||
if (n_status_strings > 0) {
|
||||
printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ",
|
||||
@@ -253,13 +234,44 @@ char *OSSL_CMP_CTX_snprint_PKIStatus(OSSL_CMP_CTX *ctx, char *buf,
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
|
||||
char *buf, size_t bufsize)
|
||||
{
|
||||
int failure_info;
|
||||
|
||||
if (statusInfo == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
failure_info = ossl_cmp_pkisi_get_pkifailureinfo(statusInfo);
|
||||
|
||||
return snprint_PKIStatusInfo_parts(ASN1_INTEGER_get(statusInfo->status),
|
||||
failure_info,
|
||||
statusInfo->statusString, buf, bufsize);
|
||||
}
|
||||
|
||||
char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
CMPerr(0, CMP_R_NULL_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return snprint_PKIStatusInfo_parts(OSSL_CMP_CTX_get_status(ctx),
|
||||
OSSL_CMP_CTX_get_failInfoCode(ctx),
|
||||
OSSL_CMP_CTX_get0_statusString(ctx),
|
||||
buf, bufsize);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Creates a new PKIStatusInfo structure and fills it in
|
||||
* returns a pointer to the structure on success, NULL on error
|
||||
* note: strongly overlaps with TS_RESP_CTX_set_status_info()
|
||||
* and TS_RESP_CTX_add_failure_info() in ../ts/ts_rsp_sign.c
|
||||
*/
|
||||
OSSL_CMP_PKISI *ossl_cmp_statusinfo_new(int status, int fail_info,
|
||||
OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info,
|
||||
const char *text)
|
||||
{
|
||||
OSSL_CMP_PKISI *si = OSSL_CMP_PKISI_new();
|
||||
|
||||
+21
-1
@@ -144,7 +144,7 @@ int OSSL_CMP_print_to_bio(BIO *bio, const char *component, const char *file,
|
||||
|
||||
#define ERR_PRINT_BUF_SIZE 4096
|
||||
/* this is similar to ERR_print_errors_cb, but uses the CMP-specific cb type */
|
||||
void OSSL_CMP_print_errors_cb(OSSL_cmp_log_cb_t log_fn)
|
||||
void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn)
|
||||
{
|
||||
unsigned long err;
|
||||
char msg[ERR_PRINT_BUF_SIZE];
|
||||
@@ -320,6 +320,26 @@ STACK_OF(X509) *ossl_cmp_build_cert_chain(STACK_OF(X509) *certs, X509 *cert)
|
||||
return result;
|
||||
}
|
||||
|
||||
int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk,
|
||||
const char *text)
|
||||
{
|
||||
ASN1_UTF8STRING *utf8string;
|
||||
|
||||
if (!ossl_assert(sk != NULL && text != NULL))
|
||||
return 0;
|
||||
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
|
||||
return 0;
|
||||
if (!ASN1_STRING_set(utf8string, text, -1))
|
||||
goto err;
|
||||
if (!sk_ASN1_UTF8STRING_push(sk, utf8string))
|
||||
goto err;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
ASN1_UTF8STRING_free(utf8string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt,
|
||||
const ASN1_OCTET_STRING *src)
|
||||
{
|
||||
|
||||
+107
-67
@@ -167,6 +167,8 @@ int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store,
|
||||
CMPerr(0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE);
|
||||
|
||||
err:
|
||||
/* directly output any fresh errors, needed for check_msg_find_cert() */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
X509_STORE_CTX_free(csc);
|
||||
return valid;
|
||||
}
|
||||
@@ -250,17 +252,22 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
X509_STORE *ts = ctx->trusted;
|
||||
char *sub, *iss;
|
||||
int self_issued = X509_check_issued(cert, cert) == X509_V_OK;
|
||||
char *str;
|
||||
X509_VERIFY_PARAM *vpm = ts != NULL ? X509_STORE_get0_param(ts) : NULL;
|
||||
int time_cmp;
|
||||
|
||||
ossl_cmp_log2(INFO, ctx, " considering %s %s with..", desc1, desc2);
|
||||
if ((sub = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subject = %s", sub);
|
||||
if ((iss = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " issuer = %s", iss);
|
||||
OPENSSL_free(iss);
|
||||
OPENSSL_free(sub);
|
||||
ossl_cmp_log3(INFO, ctx, " considering %s%s %s with..",
|
||||
self_issued ? "self-issued ": "", desc1, desc2);
|
||||
if ((str = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0)) != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " subject = %s", str);
|
||||
OPENSSL_free(str);
|
||||
if (!self_issued) {
|
||||
str = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
|
||||
if (str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, " issuer = %s", str);
|
||||
OPENSSL_free(str);
|
||||
}
|
||||
|
||||
if (already_checked(cert, already_checked1)
|
||||
|| already_checked(cert, already_checked2)) {
|
||||
@@ -284,7 +291,7 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx,
|
||||
if (!check_kid(ctx, cert, msg->header->senderKID))
|
||||
return 0;
|
||||
/* acceptable also if there is no senderKID in msg header */
|
||||
ossl_cmp_info(ctx, " cert is acceptable");
|
||||
ossl_cmp_info(ctx, " cert seems acceptable");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -295,38 +302,49 @@ static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store,
|
||||
ossl_cmp_warn(ctx, "msg signature verification failed");
|
||||
return 0;
|
||||
}
|
||||
if (!OSSL_CMP_validate_cert_path(ctx, store, scrt)) {
|
||||
ossl_cmp_warn(ctx, "cert path validation failed");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (OSSL_CMP_validate_cert_path(ctx, store, scrt))
|
||||
return 1;
|
||||
|
||||
ossl_cmp_warn(ctx,
|
||||
"msg signature validates but cert path validation failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exceptional handling for 3GPP TS 33.310 [3G/LTE Network Domain Security
|
||||
* (NDS); Authentication Framework (AF)], only to use for IP and if the ctx
|
||||
* option is explicitly set: use self-issued certificates from extraCerts as
|
||||
* trust anchor to validate sender cert and msg -
|
||||
* (NDS); Authentication Framework (AF)], only to use for IP messages
|
||||
* and if the ctx option is explicitly set: use self-issued certificates
|
||||
* from extraCerts as trust anchor to validate sender cert and msg -
|
||||
* provided it also can validate the newly enrolled certificate
|
||||
*/
|
||||
static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
int valid = 0;
|
||||
X509_STORE *store = X509_STORE_new();
|
||||
X509_STORE *store;
|
||||
|
||||
if (store != NULL /* store does not include CRLs */
|
||||
&& ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
|
||||
1 /* self-issued only */))
|
||||
valid = check_msg_valid_cert(ctx, store, scrt, msg);
|
||||
if (valid) {
|
||||
if (!ctx->permitTAInExtraCertsForIR)
|
||||
return 0;
|
||||
|
||||
if ((store = X509_STORE_new()) == NULL
|
||||
|| !ossl_cmp_X509_STORE_add1_certs(store, msg->extraCerts,
|
||||
1 /* self-issued only */))
|
||||
goto err;
|
||||
|
||||
/* store does not include CRLs */
|
||||
valid = OSSL_CMP_validate_cert_path(ctx, store, scrt);
|
||||
if (!valid) {
|
||||
ossl_cmp_warn(ctx,
|
||||
"also exceptional 3GPP mode cert path validation failed");
|
||||
} else {
|
||||
/*
|
||||
* verify that the newly enrolled certificate (which is assumed to have
|
||||
* rid == 0) can also be validated with the same trusted store
|
||||
* verify that the newly enrolled certificate (which assumed rid ==
|
||||
* OSSL_CMP_CERTREQID) can also be validated with the same trusted store
|
||||
*/
|
||||
EVP_PKEY *privkey = OSSL_CMP_CTX_get0_newPkey(ctx, 1);
|
||||
OSSL_CMP_CERTRESPONSE *crep =
|
||||
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip, 0);
|
||||
ossl_cmp_certrepmessage_get0_certresponse(msg->body->value.ip,
|
||||
OSSL_CMP_CERTREQID);
|
||||
X509 *newcrt = ossl_cmp_certresponse_get1_certificate(privkey, crep);
|
||||
/*
|
||||
* maybe better use get_cert_status() from cmp_client.c, which catches
|
||||
@@ -335,6 +353,8 @@ static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt,
|
||||
valid = OSSL_CMP_validate_cert_path(ctx, store, newcrt);
|
||||
X509_free(newcrt);
|
||||
}
|
||||
|
||||
err:
|
||||
X509_STORE_free(store);
|
||||
return valid;
|
||||
}
|
||||
@@ -393,8 +413,13 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (mode_3gpp
|
||||
&& ((!ctx->permitTAInExtraCertsForIR
|
||||
|| ossl_cmp_msg_get_bodytype(msg) != OSSL_CMP_PKIBODY_IP)))
|
||||
return 0;
|
||||
|
||||
ossl_cmp_info(ctx,
|
||||
mode_3gpp ? "failed; trying now 3GPP mode trusting extraCerts"
|
||||
mode_3gpp ? "normal mode failed; trying now 3GPP mode trusting extraCerts"
|
||||
: "trying first normal mode using trust store");
|
||||
if (check_msg_with_certs(ctx, msg->extraCerts, "extraCerts",
|
||||
NULL, NULL, msg, mode_3gpp))
|
||||
@@ -418,6 +443,12 @@ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int no_log_cb(const char *func, const char *file, int line,
|
||||
OSSL_CMP_severity level, const char *msg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* verify message signature with any acceptable and valid candidate cert */
|
||||
static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
{
|
||||
@@ -426,7 +457,7 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
char *sname = NULL;
|
||||
char *skid_str = NULL;
|
||||
const ASN1_OCTET_STRING *skid = msg->header->senderKID;
|
||||
OSSL_cmp_log_cb_t backup_log_cb = ctx->log_cb;
|
||||
OSSL_CMP_log_cb_t backup_log_cb = ctx->log_cb;
|
||||
int res = 0;
|
||||
|
||||
if (sender == NULL || msg->body == NULL)
|
||||
@@ -436,49 +467,52 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump any hitherto errors to avoid confusion when printing further ones */
|
||||
OSSL_CMP_CTX_print_errors(ctx);
|
||||
|
||||
/*
|
||||
* try first cached scrt, used successfully earlier in same transaction,
|
||||
* for validating this and any further msgs where extraCerts may be left out
|
||||
*/
|
||||
(void)ERR_set_mark();
|
||||
if (scrt != NULL
|
||||
&& cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
if (scrt != NULL) {
|
||||
(void)ERR_set_mark();
|
||||
ossl_cmp_info(ctx,
|
||||
"trying to verify msg signature with previously validated cert");
|
||||
if (cert_acceptable(ctx, "previously validated", "sender cert", scrt,
|
||||
NULL, NULL, msg)
|
||||
&& (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg)
|
||||
|| check_msg_valid_cert_3gpp(ctx, scrt, msg))) {
|
||||
(void)ERR_pop_to_mark();
|
||||
return 1;
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
return 1;
|
||||
/* cached sender cert has shown to be no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
}
|
||||
(void)ERR_pop_to_mark();
|
||||
|
||||
/* release any cached sender cert that proved no more successfully usable */
|
||||
(void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL);
|
||||
|
||||
/* enable clearing irrelevant errors in attempts to validate sender certs */
|
||||
(void)ERR_set_mark();
|
||||
ctx->log_cb = NULL; /* temporarily disable logging diagnostic info */
|
||||
|
||||
if (check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */)) {
|
||||
/* discard any diagnostic info on trying to use certs */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
ctx->log_cb = no_log_cb; /* temporarily disable logging */
|
||||
res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */)
|
||||
|| check_msg_all_certs(ctx, msg, 1 /* 3gpp */);
|
||||
ctx->log_cb = backup_log_cb;
|
||||
if (res) {
|
||||
/* discard any diagnostic information on trying to use certs */
|
||||
(void)ERR_pop_to_mark();
|
||||
res = 1;
|
||||
goto end;
|
||||
}
|
||||
/* failed finding a sender cert that verifies the message signature */
|
||||
ctx->log_cb = backup_log_cb; /* restore any logging */
|
||||
(void)ERR_clear_last_mark();
|
||||
|
||||
sname = X509_NAME_oneline(sender->d.directoryName, NULL, 0);
|
||||
skid_str = skid == NULL ? NULL
|
||||
: OPENSSL_buf2hexstr(skid->data, skid->length);
|
||||
if (ctx->log_cb != NULL) {
|
||||
ossl_cmp_info(ctx, "verifying msg signature with valid cert that..");
|
||||
ossl_cmp_info(ctx, "trying to verify msg signature with a valid cert that..");
|
||||
if (sname != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg sender name = %s", sname);
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg sender = %s", sname);
|
||||
if (skid_str != NULL)
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str);
|
||||
ossl_cmp_log1(INFO, ctx, "matches msg senderKID = %s", skid_str);
|
||||
else
|
||||
ossl_cmp_info(ctx, "while msg header does not contain senderKID");
|
||||
/* re-do the above checks (just) for adding diagnostic information */
|
||||
@@ -543,6 +577,11 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
switch (nid) {
|
||||
/* 5.1.3.1. Shared Secret Information */
|
||||
case NID_id_PasswordBasedMAC:
|
||||
if (ctx->secretValue == 0) {
|
||||
CMPerr(0, CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (verify_PBMAC(msg, ctx->secretValue)) {
|
||||
/*
|
||||
* RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is
|
||||
@@ -633,8 +672,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg)
|
||||
*
|
||||
* Ensures that:
|
||||
* it has a valid body type
|
||||
* its protection is valid or absent (allowed only if callback function is
|
||||
* present and function yields non-zero result using also supplied argument)
|
||||
* its protection is valid (or invalid/absent, but only if a callback function
|
||||
* is present and yields a positive result using also the supplied argument)
|
||||
* its transaction ID matches the previous transaction ID stored in ctx (if any)
|
||||
* its recipNonce matches the previous senderNonce stored in the ctx (if any)
|
||||
*
|
||||
@@ -660,35 +699,29 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
if (msg->header->protectionAlg != 0) {
|
||||
/* detect explicitly permitted exceptions for invalid protection */
|
||||
if (!OSSL_CMP_validate_msg(ctx, msg)
|
||||
&& (cb == NULL || !(*cb)(ctx, msg, 1, cb_arg))) {
|
||||
&& (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) {
|
||||
CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* detect explicitly permitted exceptions for missing protection */
|
||||
if (cb == NULL || !(*cb)(ctx, msg, 0, cb_arg)) {
|
||||
if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) {
|
||||
CMPerr(0, CMP_R_MISSING_PROTECTION);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
|
||||
/* check CMP version number in header */
|
||||
if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) {
|
||||
CMPerr(0, CMP_R_UNEXPECTED_PVNO);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* compare received transactionID with the expected one in previous msg */
|
||||
if (ctx->transactionID != NULL
|
||||
&& (msg->header->transactionID == NULL
|
||||
@@ -720,10 +753,17 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg,
|
||||
&& !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID))
|
||||
return -1;
|
||||
|
||||
if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) {
|
||||
CMPerr(0, CMP_R_PKIBODY_ERROR);
|
||||
/*
|
||||
* Store any provided extraCerts in ctx for future use,
|
||||
* such that they are available to ctx->certConf_cb and
|
||||
* the peer does not need to send them again in the same transaction.
|
||||
* For efficiency, the extraCerts are prepended so they get used first.
|
||||
*/
|
||||
if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts,
|
||||
0 /* this allows self-issued certs */,
|
||||
1 /* no_dups */, 1 /* prepend */))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rcvd_type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
|
||||
@@ -248,6 +248,27 @@ int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
|
||||
size_t enckeylen;
|
||||
size_t ceklen;
|
||||
CMS_EncryptedContentInfo *ec;
|
||||
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Remove this when we have functionality to deserialize
|
||||
* parameters in EVP_PKEY form from an X509_ALGOR.
|
||||
* This is needed to be able to replace the EC_KEY specific decoding
|
||||
* that happens in ecdh_cms_set_peerkey() (crypto/ec/ec_ameth.c)
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
|
||||
EVP_PKEY_get0(pkey);
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
enckeylen = rek->encryptedKey->length;
|
||||
enckey = rek->encryptedKey->data;
|
||||
/* Setup all parameters to derive KEK */
|
||||
@@ -446,6 +467,32 @@ int cms_RecipientInfo_kari_encrypt(const CMS_ContentInfo *cms,
|
||||
STACK_OF(CMS_RecipientEncryptedKey) *reks;
|
||||
int i;
|
||||
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Remove this when we have figured out all the details
|
||||
* need to set up encryption right. With legacy keys, a *lot* is
|
||||
* happening in the CMS specific EVP_PKEY_ASN1_METHOD functions,
|
||||
* such as automatically setting a default KDF type, KDF digest,
|
||||
* all that kind of stuff.
|
||||
* With EVP_SIGNATURE, setting a default digest is done by getting
|
||||
* the default MD for the key, and then inject that back into the
|
||||
* signature implementation... we could do something similar with
|
||||
* CMS, possibly using CMS specific OSSL_PARAM keys, just like we
|
||||
* have for certain AlgorithmIdentifier retrievals.
|
||||
*
|
||||
* THIS IS TEMPORARY
|
||||
*/
|
||||
EVP_PKEY_CTX *pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
|
||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||
|
||||
EVP_PKEY_get0(pkey);
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT,
|
||||
CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ri->type != CMS_RECIPINFO_AGREE) {
|
||||
CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
|
||||
return 0;
|
||||
|
||||
@@ -174,7 +174,7 @@ int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
|
||||
* the "CONF classic" functions, for consistency.
|
||||
*/
|
||||
|
||||
CONF *NCONF_new(CONF_METHOD *meth)
|
||||
CONF *NCONF_new_with_libctx(OPENSSL_CTX *libctx, CONF_METHOD *meth)
|
||||
{
|
||||
CONF *ret;
|
||||
|
||||
@@ -183,13 +183,19 @@ CONF *NCONF_new(CONF_METHOD *meth)
|
||||
|
||||
ret = meth->create(meth);
|
||||
if (ret == NULL) {
|
||||
CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CONFerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
ret->libctx = libctx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
CONF *NCONF_new(CONF_METHOD *meth)
|
||||
{
|
||||
return NCONF_new_with_libctx(NULL, meth);
|
||||
}
|
||||
|
||||
void NCONF_free(CONF *conf)
|
||||
{
|
||||
if (conf == NULL)
|
||||
|
||||
+33
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 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
|
||||
@@ -13,8 +13,10 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/conf.h"
|
||||
#include "internal/dso.h"
|
||||
#include "internal/thread_once.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/trace.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#define DSO_mod_init_name "OPENSSL_init"
|
||||
#define DSO_mod_finish_name "OPENSSL_finish"
|
||||
@@ -55,6 +57,8 @@ struct conf_imodule_st {
|
||||
static STACK_OF(CONF_MODULE) *supported_modules = NULL;
|
||||
static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
|
||||
|
||||
static CRYPTO_ONCE load_builtin_modules = CRYPTO_ONCE_STATIC_INIT;
|
||||
|
||||
static void module_free(CONF_MODULE *md);
|
||||
static void module_finish(CONF_IMODULE *imod);
|
||||
static int module_run(const CONF *cnf, const char *name, const char *value,
|
||||
@@ -113,22 +117,25 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
|
||||
|
||||
}
|
||||
|
||||
int CONF_modules_load_file(const char *filename, const char *appname,
|
||||
unsigned long flags)
|
||||
int CONF_modules_load_file_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *filename,
|
||||
const char *appname, unsigned long flags)
|
||||
{
|
||||
char *file = NULL;
|
||||
CONF *conf = NULL;
|
||||
int ret = 0;
|
||||
conf = NCONF_new(NULL);
|
||||
|
||||
conf = NCONF_new_with_libctx(libctx, NULL);
|
||||
if (conf == NULL)
|
||||
goto err;
|
||||
|
||||
if (filename == NULL) {
|
||||
file = CONF_get1_default_config_file();
|
||||
if (!file)
|
||||
if (file == NULL)
|
||||
goto err;
|
||||
} else
|
||||
} else {
|
||||
file = (char *)filename;
|
||||
}
|
||||
|
||||
if (NCONF_load(conf, file, NULL) <= 0) {
|
||||
if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
|
||||
@@ -152,12 +159,32 @@ int CONF_modules_load_file(const char *filename, const char *appname,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CONF_modules_load_file(const char *filename,
|
||||
const char *appname, unsigned long flags)
|
||||
{
|
||||
return CONF_modules_load_file_with_libctx(NULL, filename, appname, flags);
|
||||
}
|
||||
|
||||
DEFINE_RUN_ONCE_STATIC(do_load_builtin_modules)
|
||||
{
|
||||
OPENSSL_load_builtin_modules();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Need to load ENGINEs */
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
ERR_clear_error();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int module_run(const CONF *cnf, const char *name, const char *value,
|
||||
unsigned long flags)
|
||||
{
|
||||
CONF_MODULE *md;
|
||||
int ret;
|
||||
|
||||
if (!RUN_ONCE(&load_builtin_modules, do_load_builtin_modules))
|
||||
return -1;
|
||||
|
||||
md = module_find(name);
|
||||
|
||||
/* Module not found: try to load DSO */
|
||||
|
||||
@@ -59,12 +59,6 @@ int openssl_config_int(const OPENSSL_INIT_SETTINGS *settings)
|
||||
filename, appname, flags);
|
||||
#endif
|
||||
|
||||
OPENSSL_load_builtin_modules();
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* Need to load ENGINEs */
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
ERR_clear_error();
|
||||
#ifndef OPENSSL_SYS_UEFI
|
||||
ret = CONF_modules_load_file(filename, appname, flags);
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include "crypto/cryptlib.h"
|
||||
#include <openssl/conf.h>
|
||||
#include "internal/thread_once.h"
|
||||
#include "internal/property.h"
|
||||
|
||||
@@ -145,6 +146,13 @@ OPENSSL_CTX *OPENSSL_CTX_new(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int OPENSSL_CTX_load_config(OPENSSL_CTX *ctx, const char *config_file)
|
||||
{
|
||||
return CONF_modules_load_file_with_libctx(ctx, config_file, NULL, 0) > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void OPENSSL_CTX_free(OPENSSL_CTX *ctx)
|
||||
{
|
||||
if (ctx != NULL)
|
||||
@@ -164,6 +172,15 @@ OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int openssl_ctx_is_default(OPENSSL_CTX *ctx)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL || ctx == default_context)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
|
||||
CRYPTO_EX_DATA *ad, int index,
|
||||
long argl_ign, void *argp)
|
||||
|
||||
+10
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
@@ -30,6 +30,15 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
|
||||
"iterationcount below 100"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY),
|
||||
"popo inconsistent public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY),
|
||||
"popo missing public key"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT),
|
||||
"popo missing subject"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED),
|
||||
"popo raverified not accepted"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE),
|
||||
"setting mac algor failure"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE),
|
||||
@@ -44,8 +53,6 @@ static const ERR_STRING_DATA CRMF_str_reasons[] = {
|
||||
"unsupported method for creating popo"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD),
|
||||
"unsupported popo method"},
|
||||
{ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED),
|
||||
"unsupported popo not accepted"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
+63
-82
@@ -303,7 +303,7 @@ static int crmf_asn1_get_int(const ASN1_INTEGER *a)
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
int OSSL_CRMF_MSG_get_certReqId(OSSL_CRMF_MSG *crm)
|
||||
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm)
|
||||
{
|
||||
if (crm == NULL || /* not really needed: */ crm->certReq == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSG_GET_CERTREQID, CRMF_R_NULL_ARGUMENT);
|
||||
@@ -367,65 +367,30 @@ static int CRMF_poposigningkey_init(OSSL_CRMF_POPOSIGNINGKEY *ps,
|
||||
OSSL_CRMF_CERTREQUEST *cr,
|
||||
EVP_PKEY *pkey, int dgst)
|
||||
{
|
||||
int len;
|
||||
size_t crlen;
|
||||
size_t siglen;
|
||||
unsigned char *crder = NULL, *sig = NULL;
|
||||
int alg_nid = 0;
|
||||
int md_nid = 0;
|
||||
const EVP_MD *alg = NULL;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
int ret = 0;
|
||||
EVP_MD *fetched_md = NULL;
|
||||
const EVP_MD *md = EVP_get_digestbynid(dgst);
|
||||
|
||||
if (ps == NULL || cr == NULL || pkey == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* OpenSSL defaults all bit strings to be encoded as ASN.1 NamedBitList */
|
||||
ps->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
ps->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
/* If we didn't find legacy MD, we try an implicit fetch */
|
||||
if (md == NULL)
|
||||
md = fetched_md = EVP_MD_fetch(NULL, OBJ_nid2sn(dgst), NULL);
|
||||
|
||||
len = i2d_OSSL_CRMF_CERTREQUEST(cr, &crder);
|
||||
if (len < 0 || crder == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
crlen = (size_t)len;
|
||||
|
||||
if (!OBJ_find_sigid_by_algs(&alg_nid, dgst, EVP_PKEY_id(pkey))) {
|
||||
if (md == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
|
||||
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
|
||||
goto err;
|
||||
return 0;
|
||||
}
|
||||
if (!OBJ_find_sigid_algs(alg_nid, &md_nid, NULL)
|
||||
|| (alg = EVP_get_digestbynid(md_nid)) == NULL) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT,
|
||||
CRMF_R_UNSUPPORTED_ALG_FOR_POPSIGNINGKEY);
|
||||
goto err;
|
||||
}
|
||||
if (!X509_ALGOR_set0(ps->algorithmIdentifier, OBJ_nid2obj(alg_nid),
|
||||
V_ASN1_NULL, NULL)
|
||||
|| (ctx = EVP_MD_CTX_new()) == NULL
|
||||
|| EVP_DigestSignInit(ctx, NULL, alg, NULL, pkey) <= 0
|
||||
|| EVP_DigestSignUpdate(ctx, crder, crlen) <= 0
|
||||
|| EVP_DigestSignFinal(ctx, NULL, &siglen) <= 0) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if ((sig = OPENSSL_malloc(siglen)) == NULL)
|
||||
goto err;
|
||||
if (EVP_DigestSignFinal(ctx, sig, &siglen) <= 0
|
||||
|| !ASN1_BIT_STRING_set(ps->signature, sig, siglen)) {
|
||||
CRMFerr(CRMF_F_CRMF_POPOSIGNINGKEY_INIT, CRMF_R_ERROR);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(crder);
|
||||
EVP_MD_CTX_free(ctx);
|
||||
OPENSSL_free(sig);
|
||||
ret = ASN1_item_sign(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
ps->algorithmIdentifier, NULL, ps->signature,
|
||||
cr, pkey, md);
|
||||
|
||||
EVP_MD_free(fetched_md);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -520,21 +485,29 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
X509_PUBKEY *pubkey = NULL;
|
||||
OSSL_CRMF_POPOSIGNINGKEY *sig = NULL;
|
||||
|
||||
if (reqs == NULL
|
||||
|| (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL
|
||||
|| req->popo == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
|
||||
CRMF_R_NULL_ARGUMENT);
|
||||
if (reqs == NULL || (req = sk_OSSL_CRMF_MSG_value(reqs, rid)) == NULL) {
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->popo == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (req->popo->type) {
|
||||
case OSSL_CRMF_POPO_RAVERIFIED:
|
||||
if (acceptRAVerified)
|
||||
return 1;
|
||||
if (!acceptRAVerified) {
|
||||
CRMFerr(0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case OSSL_CRMF_POPO_SIGNATURE:
|
||||
pubkey = req->certReq->certTemplate->publicKey;
|
||||
if (pubkey == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
sig = req->popo->value.signature;
|
||||
if (sig->poposkInput != NULL) {
|
||||
/*
|
||||
@@ -542,26 +515,34 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
* the public key from the certificate template. This MUST be
|
||||
* exactly the same value as contained in the certificate template.
|
||||
*/
|
||||
const ASN1_ITEM *rptr = ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT);
|
||||
|
||||
if (pubkey == NULL
|
||||
|| sig->poposkInput->publicKey == NULL
|
||||
|| X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey)
|
||||
|| ASN1_item_verify(rptr, sig->algorithmIdentifier,
|
||||
sig->signature, sig->poposkInput,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
break;
|
||||
if (sig->poposkInput->publicKey == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) {
|
||||
CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* TODO check the contents of the authInfo sub-field,
|
||||
* see RFC 4211 https://tools.ietf.org/html/rfc4211#section-4.1
|
||||
*/
|
||||
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_POPOSIGNINGKEYINPUT),
|
||||
sig->algorithmIdentifier, sig->signature,
|
||||
sig->poposkInput,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
return 0;
|
||||
} else {
|
||||
if (pubkey == NULL
|
||||
|| req->certReq->certTemplate->subject == NULL
|
||||
|| ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
sig->algorithmIdentifier,
|
||||
sig->signature,
|
||||
req->certReq,
|
||||
X509_PUBKEY_get0(pubkey)) < 1)
|
||||
break;
|
||||
if (req->certReq->certTemplate->subject == NULL) {
|
||||
CRMFerr(0, CRMF_R_POPO_MISSING_SUBJECT);
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_item_verify(ASN1_ITEM_rptr(OSSL_CRMF_CERTREQUEST),
|
||||
sig->algorithmIdentifier, sig->signature,
|
||||
req->certReq, X509_PUBKEY_get0(pubkey)) < 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
case OSSL_CRMF_POPO_KEYENC:
|
||||
/*
|
||||
* TODO: when OSSL_CMP_certrep_new() supports encrypted certs,
|
||||
@@ -575,25 +556,25 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
CRMF_R_UNSUPPORTED_POPO_METHOD);
|
||||
return 0;
|
||||
}
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_MSGS_VERIFY_POPO,
|
||||
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* retrieves the serialNumber of the given cert template or NULL on error */
|
||||
ASN1_INTEGER *OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
ASN1_INTEGER
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
{
|
||||
return tmpl != NULL ? tmpl->serialNumber : NULL;
|
||||
}
|
||||
|
||||
/* retrieves the issuer name of the given cert template or NULL on error */
|
||||
X509_NAME *OSSL_CRMF_CERTTEMPLATE_get0_issuer(OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
const X509_NAME
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl)
|
||||
{
|
||||
return tmpl != NULL ? tmpl->issuer : NULL;
|
||||
}
|
||||
|
||||
/* retrieves the issuer name of the given CertId or NULL on error */
|
||||
X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid)
|
||||
const X509_NAME *OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid)
|
||||
{
|
||||
return cid != NULL && cid->issuer->type == GEN_DIRNAME ?
|
||||
cid->issuer->d.directoryName : NULL;
|
||||
@@ -619,9 +600,9 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
||||
CRMFerr(CRMF_F_OSSL_CRMF_CERTTEMPLATE_FILL, CRMF_R_NULL_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
if (subject != NULL && !X509_NAME_set(&tmpl->subject, subject))
|
||||
if (subject != NULL && !X509_NAME_set((X509_NAME **)&tmpl->subject, subject))
|
||||
return 0;
|
||||
if (issuer != NULL && !X509_NAME_set(&tmpl->issuer, issuer))
|
||||
if (issuer != NULL && !X509_NAME_set((X509_NAME **)&tmpl->issuer, issuer))
|
||||
return 0;
|
||||
if (serial != NULL) {
|
||||
ASN1_INTEGER_free(tmpl->serialNumber);
|
||||
@@ -641,7 +622,7 @@ int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
||||
* returns a pointer to the decrypted certificate
|
||||
* returns NULL on error or if no certificate available
|
||||
*/
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
X509 *OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
EVP_PKEY *pkey)
|
||||
{
|
||||
X509 *cert = NULL; /* decrypted certificate */
|
||||
|
||||
@@ -315,9 +315,9 @@ struct ossl_crmf_certtemplate_st {
|
||||
/* This field is assigned by the CA during certificate creation */
|
||||
X509_ALGOR *signingAlg; /* signingAlg MUST be omitted */
|
||||
/* This field is assigned by the CA during certificate creation */
|
||||
X509_NAME *issuer;
|
||||
const X509_NAME *issuer;
|
||||
OSSL_CRMF_OPTIONALVALIDITY *validity;
|
||||
X509_NAME *subject;
|
||||
const X509_NAME *subject;
|
||||
X509_PUBKEY *publicKey;
|
||||
ASN1_BIT_STRING *issuerUID; /* deprecated in version 2 */
|
||||
/* According to rfc 3280: UniqueIdentifier ::= BIT STRING */
|
||||
|
||||
+14
-5
@@ -132,7 +132,9 @@ SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
|
||||
* 0 on decoding failure, or invalid parameter if any
|
||||
* -1 on internal (malloc) failure
|
||||
*/
|
||||
int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
|
||||
int CTLOG_new_from_base64_with_libctx(CTLOG **ct_log, const char *pkey_base64,
|
||||
const char *name, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
unsigned char *pkey_der = NULL;
|
||||
int pkey_der_len;
|
||||
@@ -140,13 +142,13 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (ct_log == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
CTerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
|
||||
if (pkey_der_len < 0) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
|
||||
CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -154,11 +156,11 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
|
||||
OPENSSL_free(pkey_der);
|
||||
if (pkey == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
|
||||
CTerr(0, CT_R_LOG_CONF_INVALID_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*ct_log = CTLOG_new(pkey, name);
|
||||
*ct_log = CTLOG_new_with_libctx(pkey, name, libctx, propq);
|
||||
if (*ct_log == NULL) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
@@ -166,3 +168,10 @@ int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *n
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64,
|
||||
const char *name)
|
||||
{
|
||||
return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, name, NULL,
|
||||
NULL);
|
||||
}
|
||||
@@ -100,6 +100,9 @@ struct sct_ctx_st {
|
||||
size_t prederlen;
|
||||
/* milliseconds since epoch (to check that the SCT isn't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
};
|
||||
|
||||
/* Context when evaluating whether a Certificate Transparency policy is met */
|
||||
@@ -109,12 +112,15 @@ struct ct_policy_eval_ctx_st {
|
||||
CTLOG_STORE *log_store;
|
||||
/* milliseconds since epoch (to check that SCTs aren't from the future) */
|
||||
uint64_t epoch_time_in_ms;
|
||||
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new context for verifying an SCT.
|
||||
*/
|
||||
SCT_CTX *SCT_CTX_new(void);
|
||||
SCT_CTX *SCT_CTX_new(OPENSSL_CTX *ctx, const char *propq);
|
||||
/*
|
||||
* Deletes an SCT verification context.
|
||||
*/
|
||||
|
||||
+60
-14
@@ -22,6 +22,8 @@
|
||||
* Information about a CT log server.
|
||||
*/
|
||||
struct ctlog_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
char *name;
|
||||
uint8_t log_id[CT_V1_HASHLEN];
|
||||
EVP_PKEY *public_key;
|
||||
@@ -32,6 +34,8 @@ struct ctlog_st {
|
||||
* It takes ownership of any CTLOG instances added to it.
|
||||
*/
|
||||
struct ctlog_store_st {
|
||||
OPENSSL_CTX *libctx;
|
||||
char *propq;
|
||||
STACK_OF(CTLOG) *logs;
|
||||
};
|
||||
|
||||
@@ -70,53 +74,78 @@ static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
|
||||
}
|
||||
|
||||
/* Converts a log's public key into a SHA256 log ID */
|
||||
static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey,
|
||||
unsigned char log_id[CT_V1_HASHLEN])
|
||||
static int ct_v1_log_id_from_pkey(CTLOG *log, EVP_PKEY *pkey)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *pkey_der = NULL;
|
||||
int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
|
||||
unsigned int len;
|
||||
EVP_MD *sha256 = NULL;
|
||||
|
||||
if (pkey_der_len <= 0) {
|
||||
CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
|
||||
goto err;
|
||||
}
|
||||
sha256 = EVP_MD_fetch(log->libctx, "SHA2-256", log->propq);
|
||||
if (sha256 == NULL) {
|
||||
CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, ERR_LIB_EVP);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = EVP_Digest(pkey_der, pkey_der_len, log_id, &len, EVP_sha256(), NULL);
|
||||
ret = EVP_Digest(pkey_der, pkey_der_len, log->log_id, &len, sha256,
|
||||
NULL);
|
||||
err:
|
||||
EVP_MD_free(sha256);
|
||||
OPENSSL_free(pkey_der);
|
||||
return ret;
|
||||
}
|
||||
|
||||
CTLOG_STORE *CTLOG_STORE_new(void)
|
||||
CTLOG_STORE *CTLOG_STORE_new_with_libctx(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ret->propq = OPENSSL_strdup(propq);
|
||||
if (ret->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret->logs = sk_CTLOG_new_null();
|
||||
if (ret->logs == NULL)
|
||||
if (ret->logs == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
OPENSSL_free(ret);
|
||||
CTLOG_STORE_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CTLOG_STORE *CTLOG_STORE_new(void)
|
||||
{
|
||||
return CTLOG_STORE_new_with_libctx(NULL, NULL);
|
||||
}
|
||||
|
||||
void CTLOG_STORE_free(CTLOG_STORE *store)
|
||||
{
|
||||
if (store != NULL) {
|
||||
OPENSSL_free(store->propq);
|
||||
sk_CTLOG_pop_free(store->logs, CTLOG_free);
|
||||
OPENSSL_free(store);
|
||||
}
|
||||
}
|
||||
|
||||
static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section)
|
||||
static int ctlog_new_from_conf(CTLOG_STORE *store, CTLOG **ct_log,
|
||||
const CONF *conf, const char *section)
|
||||
{
|
||||
const char *description = NCONF_get_string(conf, section, "description");
|
||||
char *pkey_base64;
|
||||
@@ -132,7 +161,8 @@ static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *sec
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CTLOG_new_from_base64(ct_log, pkey_base64, description);
|
||||
return CTLOG_new_from_base64_with_libctx(ct_log, pkey_base64, description,
|
||||
store->libctx, store->propq);
|
||||
}
|
||||
|
||||
int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
|
||||
@@ -168,7 +198,7 @@ static int ctlog_store_load_log(const char *log_name, int log_name_len,
|
||||
if (tmp == NULL)
|
||||
goto mem_err;
|
||||
|
||||
ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
|
||||
ret = ctlog_new_from_conf(load_ctx->log_store, &ct_log, load_ctx->conf, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
|
||||
if (ret < 0) {
|
||||
@@ -234,22 +264,32 @@ end:
|
||||
* Takes ownership of the public key.
|
||||
* Copies the name.
|
||||
*/
|
||||
CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
|
||||
CTLOG *CTLOG_new_with_libctx(EVP_PKEY *public_key, const char *name,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ret->name = OPENSSL_strdup(propq);
|
||||
if (ret->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret->name = OPENSSL_strdup(name);
|
||||
if (ret->name == NULL) {
|
||||
CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
|
||||
if (ct_v1_log_id_from_pkey(ret, public_key) != 1)
|
||||
goto err;
|
||||
|
||||
ret->public_key = public_key;
|
||||
@@ -259,12 +299,18 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
|
||||
{
|
||||
return CTLOG_new_with_libctx(public_key, name, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Frees CT log and associated structures */
|
||||
void CTLOG_free(CTLOG *log)
|
||||
{
|
||||
if (log != NULL) {
|
||||
OPENSSL_free(log->name);
|
||||
EVP_PKEY_free(log->public_key);
|
||||
OPENSSL_free(log->propq);
|
||||
OPENSSL_free(log);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-2
@@ -25,15 +25,25 @@
|
||||
*/
|
||||
static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300;
|
||||
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new_with_libctx(OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
|
||||
|
||||
if (ctx == NULL) {
|
||||
CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
ctx->propq = OPENSSL_strdup(propq);
|
||||
if (ctx->propq == NULL) {
|
||||
CTerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* time(NULL) shouldn't ever fail, so don't bother checking for -1. */
|
||||
ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) *
|
||||
1000;
|
||||
@@ -41,12 +51,18 @@ CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
|
||||
{
|
||||
return CT_POLICY_EVAL_CTX_new_with_libctx(NULL, NULL);
|
||||
}
|
||||
|
||||
void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return;
|
||||
X509_free(ctx->cert);
|
||||
X509_free(ctx->issuer);
|
||||
OPENSSL_free(ctx->propq);
|
||||
OPENSSL_free(ctx);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -312,7 +312,7 @@ int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sctx = SCT_CTX_new();
|
||||
sctx = SCT_CTX_new(ctx->libctx, ctx->propq);
|
||||
if (sctx == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
+22
-6
@@ -20,13 +20,23 @@
|
||||
|
||||
#include "ct_local.h"
|
||||
|
||||
SCT_CTX *SCT_CTX_new(void)
|
||||
SCT_CTX *SCT_CTX_new(OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
|
||||
|
||||
if (sctx == NULL)
|
||||
CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
sctx->libctx = libctx;
|
||||
if (propq != NULL) {
|
||||
sctx->propq = OPENSSL_strdup(propq);
|
||||
if (sctx->propq == NULL) {
|
||||
CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(sctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return sctx;
|
||||
}
|
||||
|
||||
@@ -39,6 +49,7 @@ void SCT_CTX_free(SCT_CTX *sctx)
|
||||
OPENSSL_free(sctx->ihash);
|
||||
OPENSSL_free(sctx->certder);
|
||||
OPENSSL_free(sctx->preder);
|
||||
OPENSSL_free(sctx->propq);
|
||||
OPENSSL_free(sctx);
|
||||
}
|
||||
|
||||
@@ -191,13 +202,17 @@ err:
|
||||
return 0;
|
||||
}
|
||||
|
||||
__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
size_t *hash_len)
|
||||
__owur static int ct_public_key_hash(SCT_CTX *sctx, X509_PUBKEY *pkey,
|
||||
unsigned char **hash, size_t *hash_len)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char *md = NULL, *der = NULL;
|
||||
int der_len;
|
||||
unsigned int md_len;
|
||||
EVP_MD *sha256 = EVP_MD_fetch(sctx->libctx, "SHA2-256", sctx->propq);
|
||||
|
||||
if (sha256 == NULL)
|
||||
goto err;
|
||||
|
||||
/* Reuse buffer if possible */
|
||||
if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
|
||||
@@ -213,7 +228,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
if (der_len <= 0)
|
||||
goto err;
|
||||
|
||||
if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
|
||||
if (!EVP_Digest(der, der_len, md, &md_len, sha256, NULL))
|
||||
goto err;
|
||||
|
||||
if (md != *hash) {
|
||||
@@ -225,6 +240,7 @@ __owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
|
||||
md = NULL;
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_free(sha256);
|
||||
OPENSSL_free(md);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
@@ -237,7 +253,7 @@ int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
|
||||
|
||||
int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
{
|
||||
return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
|
||||
return ct_public_key_hash(sctx, pubkey, &sctx->ihash, &sctx->ihashlen);
|
||||
}
|
||||
|
||||
int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
@@ -247,7 +263,7 @@ int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
|
||||
if (pkey == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
|
||||
if (!ct_public_key_hash(sctx, pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-1
@@ -122,7 +122,8 @@ int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
|
||||
if (ctx == NULL)
|
||||
goto end;
|
||||
|
||||
if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
|
||||
if (!EVP_DigestVerifyInit_ex(ctx, NULL, "SHA2-256", sctx->propq, sctx->pkey,
|
||||
sctx->libctx))
|
||||
goto end;
|
||||
|
||||
if (!sct_ctx_update(ctx, sctx, sct))
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2020 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/der.h"
|
||||
#include "crypto/bn.h"
|
||||
|
||||
static int int_start_context(WPACKET *pkt, int tag)
|
||||
{
|
||||
if (tag < 0)
|
||||
return 1;
|
||||
if (!ossl_assert(tag <= 30))
|
||||
return 0;
|
||||
return WPACKET_start_sub_packet(pkt);
|
||||
}
|
||||
|
||||
static int int_end_context(WPACKET *pkt, int tag)
|
||||
{
|
||||
if (tag < 0)
|
||||
return 1;
|
||||
if (!ossl_assert(tag <= 30))
|
||||
return 0;
|
||||
return WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_C_CONTEXT | tag);
|
||||
}
|
||||
|
||||
int DER_w_precompiled(WPACKET *pkt, int tag,
|
||||
const unsigned char *precompiled, size_t precompiled_n)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_memcpy(pkt, precompiled, precompiled_n)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
int DER_w_boolean(WPACKET *pkt, int tag, int b)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& (!b || WPACKET_put_bytes_u8(pkt, 0xFF))
|
||||
&& !WPACKET_close(pkt)
|
||||
&& !WPACKET_put_bytes_u8(pkt, DER_P_BOOLEAN)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
static int int_der_w_integer(WPACKET *pkt, int tag,
|
||||
int (*put_bytes)(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte),
|
||||
const void *v)
|
||||
{
|
||||
unsigned int top_byte = 0;
|
||||
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& put_bytes(pkt, v, &top_byte)
|
||||
&& ((top_byte & 0x80) == 0 || WPACKET_put_bytes_u8(pkt, 0))
|
||||
&& WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_P_INTEGER)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
static int int_put_bytes_ulong(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte)
|
||||
{
|
||||
const unsigned long *value = v;
|
||||
unsigned long tmp = *value;
|
||||
size_t n = 0;
|
||||
|
||||
while (tmp != 0) {
|
||||
n++;
|
||||
*top_byte = (tmp & 0xFF);
|
||||
tmp >>= 8;
|
||||
}
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
|
||||
return WPACKET_put_bytes__(pkt, *value, n);
|
||||
}
|
||||
|
||||
/* For integers, we only support unsigned values for now */
|
||||
int DER_w_ulong(WPACKET *pkt, int tag, unsigned long v)
|
||||
{
|
||||
return int_der_w_integer(pkt, tag, int_put_bytes_ulong, &v);
|
||||
}
|
||||
|
||||
static int int_put_bytes_bn(WPACKET *pkt, const void *v,
|
||||
unsigned int *top_byte)
|
||||
{
|
||||
unsigned char *p = NULL;
|
||||
size_t n = BN_num_bytes(v);
|
||||
|
||||
/* The BIGNUM limbs are in LE order */
|
||||
*top_byte =
|
||||
((bn_get_words(v) [(n - 1) / BN_BYTES]) >> (8 * ((n - 1) % BN_BYTES)))
|
||||
& 0xFF;
|
||||
|
||||
if (!WPACKET_allocate_bytes(pkt, n, &p))
|
||||
return 0;
|
||||
if (p != NULL)
|
||||
BN_bn2bin(v, p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int DER_w_bn(WPACKET *pkt, int tag, const BIGNUM *v)
|
||||
{
|
||||
if (v == NULL || BN_is_negative(v))
|
||||
return 0;
|
||||
if (BN_is_zero(v))
|
||||
return DER_w_ulong(pkt, tag, 0);
|
||||
|
||||
return int_der_w_integer(pkt, tag, int_put_bytes_bn, v);
|
||||
}
|
||||
|
||||
int DER_w_null(WPACKET *pkt, int tag)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt)
|
||||
&& WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_P_NULL)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
|
||||
/* Constructed things need a start and an end */
|
||||
int DER_w_begin_sequence(WPACKET *pkt, int tag)
|
||||
{
|
||||
return int_start_context(pkt, tag)
|
||||
&& WPACKET_start_sub_packet(pkt);
|
||||
}
|
||||
|
||||
int DER_w_end_sequence(WPACKET *pkt, int tag)
|
||||
{
|
||||
return WPACKET_close(pkt)
|
||||
&& WPACKET_put_bytes_u8(pkt, DER_F_CONSTRUCTED | DER_P_SEQUENCE)
|
||||
&& int_end_context(pkt, tag);
|
||||
}
|
||||
+10
-7
@@ -15,20 +15,23 @@ ENDIF
|
||||
|
||||
LIBS=../../libcrypto
|
||||
$COMMON=set_key.c ecb3_enc.c $DESASM
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
ecb_enc.c cbc_enc.c \
|
||||
cfb64enc.c cfb64ede.c cfb_enc.c \
|
||||
ofb64ede.c ofb64enc.c ofb_enc.c \
|
||||
str2key.c pcbc_enc.c qud_cksm.c rand_key.c \
|
||||
fcrypt.c xcbc_enc.c cbc_cksm.c
|
||||
$ALL=$COMMON\
|
||||
ecb_enc.c cbc_enc.c \
|
||||
cfb64enc.c cfb64ede.c cfb_enc.c \
|
||||
ofb64ede.c ofb64enc.c ofb_enc.c \
|
||||
str2key.c pcbc_enc.c qud_cksm.c rand_key.c \
|
||||
fcrypt.c xcbc_enc.c cbc_cksm.c
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
DEFINE[../../libcrypto]=$DESDEF
|
||||
DEFINE[../../providers/libfips.a]=$DESDEF
|
||||
DEFINE[../../providers/liblegacy.a]=$DESDEF
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# DES functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} && !$disabled{"mdc2"} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=set_key.c $DESASM
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
DEFINE[../../providers/liblegacy.a]=$DESDEF
|
||||
ENDIF
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c
|
||||
$COMMON=dh_lib.c dh_key.c dh_group_params.c dh_check.c dh_backend.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dh_asn1.c dh_gen.c dh_err.c dh_depr.c \
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq
|
||||
/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx
|
||||
/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,3 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM=
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,16 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o
|
||||
AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh
|
||||
z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo
|
||||
pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW
|
||||
aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA
|
||||
Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5
|
||||
8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F
|
||||
SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt
|
||||
gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok
|
||||
yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N
|
||||
a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg==
|
||||
-----END DH PARAMETERS-----
|
||||
@@ -1,14 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7
|
||||
vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H
|
||||
TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF
|
||||
bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1
|
||||
rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE
|
||||
EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9
|
||||
bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3
|
||||
W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH
|
||||
ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb
|
||||
NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR
|
||||
jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=
|
||||
-----END DH PARAMETERS-----
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
-----BEGIN DH PARAMETERS-----
|
||||
MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn
|
||||
a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC
|
||||
-----END DH PARAMETERS-----
|
||||
+58
-21
@@ -20,10 +20,12 @@
|
||||
#include "dh_local.h"
|
||||
#include <openssl/bn.h>
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/dh.h"
|
||||
#include "crypto/evp.h"
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "internal/ffc.h"
|
||||
|
||||
/*
|
||||
* i2d/d2i like DH parameter functions which use the appropriate routine for
|
||||
@@ -489,48 +491,82 @@ static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
DH *dh = from->pkey.dh;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
|
||||
const BIGNUM *pub_key = DH_get0_pub_key(dh);
|
||||
const BIGNUM *priv_key = DH_get0_priv_key(dh);
|
||||
OSSL_PARAM *params;
|
||||
int rv;
|
||||
OSSL_PARAM *params = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
/*
|
||||
* If the DH method is foreign, then we can't be sure of anything, and
|
||||
* can therefore not export or pretend to export.
|
||||
*/
|
||||
if (dh_get_method(dh) != DH_OpenSSL())
|
||||
return 0;
|
||||
|
||||
if (p == NULL || g == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
goto err;
|
||||
if (q != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
|
||||
return 0;
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
|
||||
goto err;
|
||||
}
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
if (pub_key != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
/* A key must at least have a public part. */
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
|
||||
return 0;
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key))
|
||||
return 0;
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
return 0;
|
||||
if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
ossl_param_bld_free(params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
err:
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int dh_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
DH *dh = DH_new();
|
||||
|
||||
if (dh == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ffc_fromdata(dh_get0_params(dh), params)
|
||||
|| !dh_key_fromdata(dh, params)
|
||||
|| !EVP_PKEY_assign_DH(pkey, dh)) {
|
||||
DH_free(dh);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
|
||||
EVP_PKEY_DH,
|
||||
EVP_PKEY_DH,
|
||||
@@ -573,6 +609,7 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
|
||||
|
||||
dh_pkey_dirty_cnt,
|
||||
dh_pkey_export_to,
|
||||
dh_pkey_import_from,
|
||||
};
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2020 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 <openssl/core_names.h>
|
||||
#include "crypto/dh.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend functions
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int dh_key_fromdata(DH *dh, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key, *param_pub_key;
|
||||
BIGNUM *priv_key = NULL, *pub_key = NULL;
|
||||
|
||||
if (dh == NULL)
|
||||
return 0;
|
||||
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
|
||||
/*
|
||||
* DH documentation says that a public key must be present if a
|
||||
* private key is present.
|
||||
* We want to have at least a public key either way, so we end up
|
||||
* requiring it unconditionally.
|
||||
*/
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if ((param_priv_key != NULL
|
||||
&& !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
|| (param_pub_key != NULL
|
||||
&& !OSSL_PARAM_get_BN(param_pub_key, &pub_key)))
|
||||
goto err;
|
||||
|
||||
if (!DH_set0_key(dh, pub_key, priv_key))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_clear_free(priv_key);
|
||||
BN_free(pub_key);
|
||||
return 0;
|
||||
}
|
||||
+6
-1
@@ -45,6 +45,11 @@ int DH_set_method(DH *dh, const DH_METHOD *meth)
|
||||
return 1;
|
||||
}
|
||||
|
||||
const DH_METHOD *dh_get_method(const DH *dh)
|
||||
{
|
||||
return dh->meth;
|
||||
}
|
||||
|
||||
DH *DH_new(void)
|
||||
{
|
||||
return dh_new_intern(NULL, NULL);
|
||||
@@ -166,7 +171,7 @@ int DH_set_ex_data(DH *d, int idx, void *arg)
|
||||
return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *DH_get_ex_data(DH *d, int idx)
|
||||
void *DH_get_ex_data(const DH *d, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&d->ex_data, idx);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_aid.c dsa_check.c \
|
||||
dsa_key.c
|
||||
$COMMON=dsa_sign.c dsa_vrf.c dsa_lib.c dsa_ossl.c dsa_check.c \
|
||||
dsa_key.c dsa_backend.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON\
|
||||
dsa_gen.c dsa_asn1.c \
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 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 <stdlib.h>
|
||||
|
||||
#include <openssl/objects.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
#define ASN1_SEQUENCE 0x30
|
||||
#define ASN1_OID 0x06
|
||||
|
||||
/*
|
||||
* id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
|
||||
* iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3
|
||||
* }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_RFC3279(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x09, \
|
||||
ASN1_OID, 0x07, 1 * 40 + 2, 134, 72, 206, 56, 4, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_RFC3279(sha1, 3);
|
||||
|
||||
/*
|
||||
* dsaWithSHAx OIDs are of the form: (sigAlgs |n|)
|
||||
* where sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 }
|
||||
*/
|
||||
#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \
|
||||
static const unsigned char algorithmidentifier_##name##_der[] = { \
|
||||
ASN1_SEQUENCE, 0x0b, \
|
||||
ASN1_OID, 0x09, 2 * 40 + 16, 0x86, 0x48, 1, 101, 3, 4, 3, n \
|
||||
}
|
||||
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha224, 1);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha256, 2);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha384, 3);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha512, 4);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 5);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 6);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 7);
|
||||
ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 8);
|
||||
|
||||
#define MD_CASE(name) \
|
||||
case NID_##name: \
|
||||
*len = sizeof(algorithmidentifier_##name##_der); \
|
||||
return algorithmidentifier_##name##_der
|
||||
|
||||
const unsigned char *dsa_algorithmidentifier_encoding(int md_nid, size_t *len)
|
||||
{
|
||||
switch (md_nid) {
|
||||
MD_CASE(sha1);
|
||||
MD_CASE(sha224);
|
||||
MD_CASE(sha256);
|
||||
MD_CASE(sha384);
|
||||
MD_CASE(sha512);
|
||||
MD_CASE(sha3_224);
|
||||
MD_CASE(sha3_256);
|
||||
MD_CASE(sha3_384);
|
||||
MD_CASE(sha3_512);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+59
-20
@@ -21,8 +21,10 @@
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/dsa.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "internal/ffc.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
|
||||
@@ -518,45 +520,81 @@ static size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
DSA *dsa = from->pkey.dsa;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa);
|
||||
const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa);
|
||||
const BIGNUM *priv_key = DSA_get0_priv_key(dsa);
|
||||
OSSL_PARAM *params;
|
||||
int rv;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
/*
|
||||
* If the DSA method is foreign, then we can't be sure of anything, and
|
||||
* can therefore not export or pretend to export.
|
||||
*/
|
||||
if (DSA_get_method(dsa) != DSA_OpenSSL())
|
||||
return 0;
|
||||
|
||||
if (p == NULL || q == NULL || g == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
|
||||
|| !ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
return 0;
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key))
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)
|
||||
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
if (pub_key != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
if (priv_key != NULL) {
|
||||
if (!ossl_param_bld_push_BN(&tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key))
|
||||
return 0;
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
if ((params = ossl_param_bld_to_param(&tmpl)) == NULL)
|
||||
return 0;
|
||||
if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
|
||||
goto err;
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
|
||||
ossl_param_bld_free(params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
err:
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int dsa_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
DSA *dsa = DSA_new();
|
||||
|
||||
if (dsa == NULL) {
|
||||
ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ffc_fromdata(dsa_get0_params(dsa), params)
|
||||
|| !dsa_key_fromdata(dsa, params)
|
||||
|| !EVP_PKEY_assign_DSA(pkey, dsa)) {
|
||||
DSA_free(dsa);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* NB these are sorted in pkey_id order, lowest first */
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
|
||||
@@ -620,6 +658,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
|
||||
dsa_pkey_dirty_cnt,
|
||||
dsa_pkey_export_to
|
||||
dsa_pkey_export_to,
|
||||
dsa_pkey_import_from
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2020 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 <openssl/core_names.h>
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key, *param_pub_key;
|
||||
BIGNUM *priv_key = NULL, *pub_key = NULL;
|
||||
|
||||
if (dsa == NULL)
|
||||
return 0;
|
||||
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
|
||||
/* It's ok if neither half is present */
|
||||
if (param_priv_key == NULL && param_pub_key == NULL)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* DH documentation says that a public key must be present if a
|
||||
* private key is present.
|
||||
*/
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
|
||||
goto err;
|
||||
if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
goto err;
|
||||
|
||||
if (!DSA_set0_key(dsa, pub_key, priv_key))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_clear_free(priv_key);
|
||||
BN_free(pub_key);
|
||||
return 0;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ int DSA_set_ex_data(DSA *d, int idx, void *arg)
|
||||
return CRYPTO_set_ex_data(&d->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *DSA_get_ex_data(DSA *d, int idx)
|
||||
void *DSA_get_ex_data(const DSA *d, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&d->ex_data, idx);
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
|
||||
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
|
||||
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
|
||||
$ECASM
|
||||
$ECASM ec_backend.c ecx_backend.c
|
||||
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
|
||||
@@ -5438,13 +5438,14 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
}
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32])
|
||||
const uint8_t public_key[32], const uint8_t private_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
||||
ge_p3 R;
|
||||
uint8_t hram[SHA512_DIGEST_LENGTH];
|
||||
EVP_MD *sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
EVP_MD *sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
|
||||
unsigned int sz;
|
||||
int res = 0;
|
||||
@@ -5493,7 +5494,8 @@ err:
|
||||
static const char allzeroes[15];
|
||||
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32])
|
||||
const uint8_t signature[64], const uint8_t public_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
int i;
|
||||
ge_p3 A;
|
||||
@@ -5548,7 +5550,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
fe_neg(A.X, A.X);
|
||||
fe_neg(A.T, A.T);
|
||||
|
||||
sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
if (sha512 == NULL)
|
||||
return 0;
|
||||
hash_ctx = EVP_MD_CTX_new();
|
||||
|
||||
@@ -10,15 +10,6 @@
|
||||
# define OSSL_CRYPTO_EC_CURVE448_LOCAL_H
|
||||
# include "curve448utils.h"
|
||||
|
||||
int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message,
|
||||
size_t message_len, const uint8_t public_key[57],
|
||||
const uint8_t private_key[57], const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[114], const uint8_t public_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/ecx.h"
|
||||
#include "curve448_local.h"
|
||||
#include "word.h"
|
||||
#include "ed448.h"
|
||||
|
||||
+70
-28
@@ -23,7 +23,7 @@
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
@@ -611,7 +611,7 @@ int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
if ((curve_name = OBJ_nid2sn(curve_nid)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0))
|
||||
if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -620,47 +620,65 @@ int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
|
||||
static
|
||||
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
const EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
unsigned char *pub_key_buf = NULL;
|
||||
size_t pub_key_buflen;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const BIGNUM *priv_key = NULL;
|
||||
const EC_POINT *pub_point = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
BN_CTX *bnctx = NULL;
|
||||
|
||||
if (from == NULL
|
||||
|| (eckey = from->pkey.ec) == NULL
|
||||
|| (ecg = EC_KEY_get0_group(eckey)) == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
/*
|
||||
* If the EC_KEY method is foreign, then we can't be sure of anything,
|
||||
* and can therefore not export or pretend to export.
|
||||
*/
|
||||
if (EC_KEY_get_method(eckey) != EC_KEY_OpenSSL())
|
||||
return 0;
|
||||
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
/* export the domain parameters */
|
||||
if (!ecparams_to_params(eckey, &tmpl))
|
||||
return 0;
|
||||
if (!ecparams_to_params(eckey, tmpl))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
pub_point = EC_KEY_get0_public_key(eckey);
|
||||
|
||||
/* public_key must be present, priv_key is optional */
|
||||
if (pub_point == NULL)
|
||||
return 0;
|
||||
if (pub_point != NULL) {
|
||||
/*
|
||||
* EC_POINT_point2buf() can generate random numbers in some
|
||||
* implementations so we need to ensure we use the correct libctx.
|
||||
*/
|
||||
bnctx = BN_CTX_new_ex(libctx);
|
||||
if (bnctx == NULL)
|
||||
goto err;
|
||||
|
||||
/* convert pub_point to a octet string according to the SECG standard */
|
||||
if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
|
||||
POINT_CONVERSION_COMPRESSED,
|
||||
&pub_key_buf, NULL)) == 0)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl,
|
||||
OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key_buf,
|
||||
pub_key_buflen))
|
||||
goto err;
|
||||
/* convert pub_point to a octet string according to the SECG standard */
|
||||
if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
|
||||
POINT_CONVERSION_COMPRESSED,
|
||||
&pub_key_buf, bnctx)) == 0
|
||||
|| !OSSL_PARAM_BLD_push_octet_string(tmpl,
|
||||
OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key_buf,
|
||||
pub_key_buflen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
|
||||
if (priv_key != NULL) {
|
||||
size_t sz;
|
||||
@@ -705,10 +723,11 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
goto err;
|
||||
|
||||
sz = (ecbits + 7 ) / 8;
|
||||
if (!ossl_param_bld_push_BN_pad(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key, sz))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
|
||||
/*
|
||||
* The ECDH Cofactor Mode is defined only if the EC_KEY actually
|
||||
@@ -719,24 +738,46 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
(EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
|
||||
|
||||
/* Export the ECDH_COFACTOR_MODE parameter */
|
||||
if (!ossl_param_bld_push_int(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_int(tmpl,
|
||||
OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
|
||||
ecdh_cofactor_mode))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
params = OSSL_PARAM_BLD_to_param(tmpl);
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
err:
|
||||
ossl_param_bld_free(params);
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OPENSSL_free(pub_key_buf);
|
||||
BN_CTX_free(bnctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ec_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
EC_KEY *ec = EC_KEY_new();
|
||||
|
||||
if (ec == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ec_key_domparams_fromdata(ec, params)
|
||||
|| !ec_key_otherparams_fromdata(ec, params)
|
||||
|| !ec_key_fromdata(ec, params, 1)
|
||||
|| !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
EC_KEY_free(ec);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
EVP_PKEY_EC,
|
||||
EVP_PKEY_EC,
|
||||
@@ -782,7 +823,8 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
0, /* get_pub_key */
|
||||
|
||||
ec_pkey_dirty_cnt,
|
||||
ec_pkey_export_to
|
||||
ec_pkey_export_to,
|
||||
ec_pkey_import_from
|
||||
};
|
||||
|
||||
#if !defined(OPENSSL_NO_SM2)
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2020 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 <openssl/core_names.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/params.h>
|
||||
#include "crypto/bn.h"
|
||||
#include "crypto/ec.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ec_set_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p)
|
||||
{
|
||||
const EC_GROUP *ecg = EC_KEY_get0_group(ec);
|
||||
const BIGNUM *cofactor;
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* mode can be only 0 for disable, or 1 for enable here.
|
||||
*
|
||||
* This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
|
||||
* also supports mode == -1 with the meaning of "reset to the default for
|
||||
* the associated key".
|
||||
*/
|
||||
if (mode < 0 || mode > 1)
|
||||
return 0;
|
||||
|
||||
if ((cofactor = EC_GROUP_get0_cofactor(ecg)) == NULL )
|
||||
return 0;
|
||||
|
||||
/* ECDH cofactor mode has no effect if cofactor is 1 */
|
||||
if (BN_is_one(cofactor))
|
||||
return 1;
|
||||
|
||||
if (mode == 1)
|
||||
EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
|
||||
else if (mode == 0)
|
||||
EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callers of ec_key_fromdata MUST make sure that ec_key_params_fromdata has
|
||||
* been called before!
|
||||
*
|
||||
* This function only gets the bare keypair, domain parameters and other
|
||||
* parameters are treated separately, and domain parameters are required to
|
||||
* define a keypair.
|
||||
*/
|
||||
int ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private)
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL;
|
||||
unsigned char *pub_key = NULL;
|
||||
size_t pub_key_len;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
EC_POINT *pub_point = NULL;
|
||||
int ok = 0;
|
||||
|
||||
ecg = EC_KEY_get0_group(ec);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (include_private)
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
|
||||
ctx = BN_CTX_new_ex(ec_key_get_libctx(ec));
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
/* OpenSSL decree: If there's a private key, there must be a public key */
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (param_pub_key != NULL)
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub_key,
|
||||
(void **)&pub_key, 0, &pub_key_len)
|
||||
|| (pub_point = EC_POINT_new(ecg)) == NULL
|
||||
|| !EC_POINT_oct2point(ecg, pub_point, pub_key, pub_key_len, ctx))
|
||||
goto err;
|
||||
|
||||
if (param_priv_key != NULL && include_private) {
|
||||
int fixed_words;
|
||||
const BIGNUM *order;
|
||||
|
||||
/*
|
||||
* Key import/export should never leak the bit length of the secret
|
||||
* scalar in the key.
|
||||
*
|
||||
* For this reason, on export we use padded BIGNUMs with fixed length.
|
||||
*
|
||||
* When importing we also should make sure that, even if short lived,
|
||||
* the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
|
||||
* soon as possible, so that any processing of this BIGNUM might opt for
|
||||
* constant time implementations in the backend.
|
||||
*
|
||||
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
|
||||
* to preallocate the BIGNUM internal buffer to a fixed public size big
|
||||
* enough that operations performed during the processing never trigger
|
||||
* a realloc which would leak the size of the scalar through memory
|
||||
* accesses.
|
||||
*
|
||||
* Fixed Length
|
||||
* ------------
|
||||
*
|
||||
* The order of the large prime subgroup of the curve is our choice for
|
||||
* a fixed public size, as that is generally the upper bound for
|
||||
* generating a private key in EC cryptosystems and should fit all valid
|
||||
* secret scalars.
|
||||
*
|
||||
* For padding on export we just use the bit length of the order
|
||||
* converted to bytes (rounding up).
|
||||
*
|
||||
* For preallocating the BIGNUM storage we look at the number of "words"
|
||||
* required for the internal representation of the order, and we
|
||||
* preallocate 2 extra "words" in case any of the subsequent processing
|
||||
* might temporarily overflow the order length.
|
||||
*/
|
||||
order = EC_GROUP_get0_order(ecg);
|
||||
if (order == NULL || BN_is_zero(order))
|
||||
goto err;
|
||||
|
||||
fixed_words = bn_get_top(order) + 2;
|
||||
|
||||
if ((priv_key = BN_secure_new()) == NULL)
|
||||
goto err;
|
||||
if (bn_wexpand(priv_key, fixed_words) == NULL)
|
||||
goto err;
|
||||
BN_set_flags(priv_key, BN_FLG_CONSTTIME);
|
||||
|
||||
if (!OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv_key != NULL
|
||||
&& !EC_KEY_set_private_key(ec, priv_key))
|
||||
goto err;
|
||||
|
||||
if (pub_point != NULL
|
||||
&& !EC_KEY_set_public_key(ec, pub_point))
|
||||
goto err;
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(priv_key);
|
||||
OPENSSL_free(pub_key);
|
||||
EC_POINT_free(pub_point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_domparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_ec_name;
|
||||
EC_GROUP *ecg = NULL;
|
||||
char *curve_name = NULL;
|
||||
int ok = 0;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
param_ec_name = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME);
|
||||
if (param_ec_name == NULL) {
|
||||
/* explicit parameters */
|
||||
|
||||
/*
|
||||
* TODO(3.0): should we support explicit parameters curves?
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
/* named curve */
|
||||
int curve_nid;
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string(param_ec_name, &curve_name, 0)
|
||||
|| curve_name == NULL
|
||||
|| (curve_nid = ec_curve_name2nid(curve_name)) == NID_undef)
|
||||
goto err;
|
||||
|
||||
if ((ecg = EC_GROUP_new_by_curve_name_ex(ec_key_get_libctx(ec),
|
||||
curve_nid)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_group(ec, ecg))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* TODO(3.0): if the group has changed, should we invalidate the private and
|
||||
* public key?
|
||||
*/
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(curve_name);
|
||||
EC_GROUP_free(ecg);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
|
||||
if (p != NULL && !ec_set_param_ecdh_cofactor_mode(ec, p))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
+10
-10
@@ -19,27 +19,27 @@
|
||||
int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int nid = NID_undef;
|
||||
#ifndef FIPS_MODE
|
||||
int nid;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
|
||||
if (group == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
ctx = new_ctx = BN_CTX_new_ex(NULL);
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK_NAMED_CURVE, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NID_undef;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nid = ec_curve_nid_from_params(group, ctx);
|
||||
if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL)
|
||||
nid = NID_undef;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
#endif
|
||||
BN_CTX_free(new_ctx);
|
||||
return nid;
|
||||
}
|
||||
|
||||
|
||||
@@ -420,3 +420,69 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
|
||||
|
||||
return (int)ukmlen;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
|
||||
const char *name)
|
||||
{
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
OSSL_PARAM *p = params;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
|
||||
(char *)name, 0);
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
|
||||
char *name, size_t namelen)
|
||||
{
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
OSSL_PARAM *p = params;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
|
||||
name, namelen);
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, params))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
|
||||
{
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Legacy: if key type not EC return error */
|
||||
if (ctx->pmeth != NULL
|
||||
&& EVP_PKEY_type(ctx->pmeth->pkey_id) != EVP_PKEY_EC)
|
||||
return -1;
|
||||
|
||||
if (ctx->op.keymgmt.genctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
|
||||
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
|
||||
nid, NULL);
|
||||
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx, OBJ_nid2sn(nid));
|
||||
}
|
||||
#endif
|
||||
+169
-122
@@ -20,6 +20,7 @@
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "e_os.h" /* strcasecmp required by windows */
|
||||
|
||||
typedef struct {
|
||||
int field_type, /* either NID_X9_62_prime_field or
|
||||
@@ -2816,6 +2817,7 @@ static const struct {
|
||||
#endif /* OPENSSL_NO_SM2 */
|
||||
|
||||
typedef struct _ec_list_element_st {
|
||||
const char *name;
|
||||
int nid;
|
||||
const EC_CURVE_DATA *data;
|
||||
const EC_METHOD *(*meth) (void);
|
||||
@@ -2826,15 +2828,15 @@ typedef struct _ec_list_element_st {
|
||||
static const ec_list_element curve_list[] = {
|
||||
/* prime field curves */
|
||||
/* secg curves */
|
||||
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h,
|
||||
# if !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
EC_GFp_nistp224_method,
|
||||
# else
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
0,
|
||||
# endif
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
|
||||
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
{"secp384r1", NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp384_method,
|
||||
# else
|
||||
@@ -2842,7 +2844,7 @@ static const ec_list_element curve_list[] = {
|
||||
# endif
|
||||
"NIST/SECG curve over a 384 bit prime field"},
|
||||
|
||||
{NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
{"secp521r1", NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp521_method,
|
||||
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
@@ -2853,9 +2855,9 @@ static const ec_list_element curve_list[] = {
|
||||
"NIST/SECG curve over a 521 bit prime field"},
|
||||
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
{"prime192v1", NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
"NIST/X9.62/SECG curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
{"prime256v1", NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
# if defined(ECP_NISTZ256_ASM)
|
||||
EC_GFp_nistz256_method,
|
||||
# elif defined(S390X_EC_ASM)
|
||||
@@ -2870,25 +2872,25 @@ static const ec_list_element curve_list[] = {
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* characteristic two field curves */
|
||||
/* NIST/SECG curves */
|
||||
{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"sect163k1", NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
{"sect163r2", NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
"NIST/SECG curve over a 163 bit binary field"},
|
||||
{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"sect233k1", NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"sect233r1", NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
{"sect283k1", NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
{"sect283r1", NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
{"sect409k1", NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
{"sect409r1", NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
{"sect571k1", NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
{"sect571r1", NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
# endif
|
||||
};
|
||||
@@ -2898,43 +2900,43 @@ static const ec_list_element curve_list[] = {
|
||||
static const ec_list_element curve_list[] = {
|
||||
/* prime field curves */
|
||||
/* secg curves */
|
||||
{NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
{"secp112r1", NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
"SECG/WTLS curve over a 112 bit prime field"},
|
||||
{NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
|
||||
{"secp112r2", NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
|
||||
"SECG curve over a 112 bit prime field"},
|
||||
{NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
|
||||
{"secp128r1", NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
|
||||
"SECG curve over a 128 bit prime field"},
|
||||
{NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
|
||||
{"secp128r2", NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
|
||||
"SECG curve over a 128 bit prime field"},
|
||||
{NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
|
||||
{"secp160k1", NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
|
||||
"SECG curve over a 160 bit prime field"},
|
||||
{NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
|
||||
{"secp160r1", NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
|
||||
"SECG curve over a 160 bit prime field"},
|
||||
{NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
{"secp160r2", NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
"SECG/WTLS curve over a 160 bit prime field"},
|
||||
/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
|
||||
{NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
|
||||
{"secp192k1", NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
|
||||
"SECG curve over a 192 bit prime field"},
|
||||
{NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
|
||||
{"secp224k1", NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
|
||||
"SECG curve over a 224 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
# else
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
# endif
|
||||
{NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
|
||||
{"secp256k1", NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
|
||||
"SECG curve over a 256 bit prime field"},
|
||||
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
|
||||
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
{"secp384r1", NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp384_method,
|
||||
# else
|
||||
0,
|
||||
# endif
|
||||
"NIST/SECG curve over a 384 bit prime field"},
|
||||
{NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
{"secp521r1", NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp521_method,
|
||||
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
@@ -2944,19 +2946,19 @@ static const ec_list_element curve_list[] = {
|
||||
# endif
|
||||
"NIST/SECG curve over a 521 bit prime field"},
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
{"prime192v1", NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
"NIST/X9.62/SECG curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
|
||||
{"prime192v2", NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
|
||||
"X9.62 curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
|
||||
{"prime192v3", NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
|
||||
"X9.62 curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
|
||||
{"prime239v1", NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
|
||||
{"prime239v2", NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
|
||||
{"prime239v3", NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
{"prime256v1", NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
# if defined(ECP_NISTZ256_ASM)
|
||||
EC_GFp_nistz256_method,
|
||||
# elif defined(S390X_EC_ASM)
|
||||
@@ -2970,144 +2972,144 @@ static const ec_list_element curve_list[] = {
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* characteristic two field curves */
|
||||
/* NIST/SECG curves */
|
||||
{NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
{"sect113r1", NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
|
||||
{"sect113r2", NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
|
||||
{ "sect131r1", NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
|
||||
"SECG/WTLS curve over a 131 bit binary field"},
|
||||
{NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
|
||||
{ "sect131r2", NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
|
||||
"SECG curve over a 131 bit binary field"},
|
||||
{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"sect163k1", NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
|
||||
{"sect163r1", NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
|
||||
"SECG curve over a 163 bit binary field"},
|
||||
{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
{"sect163r2", NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
"NIST/SECG curve over a 163 bit binary field"},
|
||||
{NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
|
||||
{"sect193r1", NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
|
||||
"SECG curve over a 193 bit binary field"},
|
||||
{NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
|
||||
{"sect193r2", NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
|
||||
"SECG curve over a 193 bit binary field"},
|
||||
{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"sect233k1", NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"sect233r1", NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
|
||||
{"sect239k1", NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
|
||||
"SECG curve over a 239 bit binary field"},
|
||||
{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
{"sect283k1", NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
{"sect283r1", NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
{"sect409k1", NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
{"sect409r1", NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
{"sect571k1", NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
{"sect571r1", NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
{"c2pnb163v1", NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
|
||||
{"c2pnb163v2", NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
|
||||
{"c2pnb163v3", NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
|
||||
{"c2pnb176v1", NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
|
||||
"X9.62 curve over a 176 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
|
||||
{"c2tnb191v1", NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
|
||||
{"c2tnb191v2", NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
|
||||
{"c2tnb191v3", NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
|
||||
{"c2pnb208w1", NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
|
||||
"X9.62 curve over a 208 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
|
||||
{"c2tnb239v1", NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
|
||||
{"c2tnb239v2", NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
|
||||
{"c2tnb239v3", NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
|
||||
{"c2pnb272w1", NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
|
||||
"X9.62 curve over a 272 bit binary field"},
|
||||
{NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
|
||||
{"c2pnb304w1", NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
|
||||
"X9.62 curve over a 304 bit binary field"},
|
||||
{NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
|
||||
{"c2tnb359v1", NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
|
||||
"X9.62 curve over a 359 bit binary field"},
|
||||
{NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
|
||||
{"c2pnb368w1", NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
|
||||
"X9.62 curve over a 368 bit binary field"},
|
||||
{NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
|
||||
{"c2tnb431r1", NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
|
||||
"X9.62 curve over a 431 bit binary field"},
|
||||
/*
|
||||
* the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
|
||||
* from X9.62]
|
||||
*/
|
||||
{NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
|
||||
"WTLS curve over a 113 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
# endif
|
||||
{NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
"SECG/WTLS curve over a 112 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
"SECG/WTLS curve over a 160 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
|
||||
"WTLS curve over a 112 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
|
||||
"WTLS curve over a 160 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
{NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
# endif
|
||||
{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
|
||||
"WTLS curve over a 224 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* IPSec curves */
|
||||
{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
|
||||
{"Oakley-EC2N-3", NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
|
||||
"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
|
||||
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
|
||||
{NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
|
||||
{"Oakley-EC2N-4", NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
|
||||
"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
|
||||
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
|
||||
# endif
|
||||
/* brainpool curves */
|
||||
{NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
|
||||
{"brainpoolP160r1", NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
|
||||
"RFC 5639 curve over a 160 bit prime field"},
|
||||
{NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
|
||||
{"brainpoolP160t1", NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
|
||||
"RFC 5639 curve over a 160 bit prime field"},
|
||||
{NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
|
||||
{"brainpoolP192r1", NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
|
||||
"RFC 5639 curve over a 192 bit prime field"},
|
||||
{NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
|
||||
{"brainpoolP192t1", NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
|
||||
"RFC 5639 curve over a 192 bit prime field"},
|
||||
{NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
|
||||
{"brainpoolP224r1", NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
|
||||
"RFC 5639 curve over a 224 bit prime field"},
|
||||
{NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
|
||||
{"brainpoolP224t1", NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
|
||||
"RFC 5639 curve over a 224 bit prime field"},
|
||||
{NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
|
||||
{"brainpoolP256r1", NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
|
||||
"RFC 5639 curve over a 256 bit prime field"},
|
||||
{NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
|
||||
{"brainpoolP256t1", NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
|
||||
"RFC 5639 curve over a 256 bit prime field"},
|
||||
{NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
|
||||
{"brainpoolP320r1", NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
|
||||
"RFC 5639 curve over a 320 bit prime field"},
|
||||
{NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
|
||||
{"brainpoolP320t1", NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
|
||||
"RFC 5639 curve over a 320 bit prime field"},
|
||||
{NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
|
||||
{"brainpoolP384r1", NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
|
||||
"RFC 5639 curve over a 384 bit prime field"},
|
||||
{NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
|
||||
{"brainpoolP384t1", NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
|
||||
"RFC 5639 curve over a 384 bit prime field"},
|
||||
{NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
|
||||
{"brainpoolP512r1", NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
{"brainpoolP512t1", NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
# ifndef OPENSSL_NO_SM2
|
||||
{NID_sm2, &_EC_sm2p256v1.h, 0,
|
||||
{"SM2", NID_sm2, &_EC_sm2p256v1.h, 0,
|
||||
"SM2 curve over a 256 bit prime field"},
|
||||
# endif
|
||||
};
|
||||
@@ -3115,6 +3117,68 @@ static const ec_list_element curve_list[] = {
|
||||
|
||||
#define curve_list_length OSSL_NELEM(curve_list)
|
||||
|
||||
static const ec_list_element *ec_curve_nid2curve(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (nid <= 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < curve_list_length; i++) {
|
||||
if (curve_list[i].nid == nid)
|
||||
return &curve_list[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const ec_list_element *ec_curve_name2curve(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < curve_list_length; i++) {
|
||||
if (strcasecmp(curve_list[i].name, name) == 0)
|
||||
return &curve_list[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ec_curve_nid2name(int nid)
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Figure out if we should try to find the nid with
|
||||
* EC_curve_nid2nist() first, i.e. make it a priority to return
|
||||
* NIST names if there is one for the NID. This is related to
|
||||
* the TODO comment in ec_curve_name2nid().
|
||||
*/
|
||||
const ec_list_element *curve = ec_curve_nid2curve(nid);
|
||||
|
||||
if (curve != NULL)
|
||||
return curve->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ec_curve_name2nid(const char *name)
|
||||
{
|
||||
const ec_list_element *curve = NULL;
|
||||
int nid;
|
||||
|
||||
if ((nid = EC_curve_nist2nid(name)) != NID_undef)
|
||||
return nid;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* TODO(3.0) Figure out if we can use other names than the NIST names
|
||||
* ("B-163", "K-163" & "P-192") in the FIPS module, or if other names
|
||||
* are allowed as well as long as they lead to the same curve data.
|
||||
* If only the NIST names are allowed in the FIPS module, we should
|
||||
* move '#endif' to just before 'return NID_undef'.
|
||||
*/
|
||||
#endif
|
||||
if ((curve = ec_curve_name2curve(name)) != NULL)
|
||||
return curve->nid;
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
const ec_list_element curve)
|
||||
{
|
||||
@@ -3226,28 +3290,11 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid)
|
||||
{
|
||||
size_t i;
|
||||
EC_GROUP *ret = NULL;
|
||||
const ec_list_element *curve;
|
||||
|
||||
if (nid <= 0)
|
||||
return NULL;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
/*
|
||||
* Only use approved NIST curves in FIPS.
|
||||
* NOTE: "B-163", "K-163" & "P-192" can only be used for legacy use
|
||||
* (i.e- ECDSA signature verification).
|
||||
*/
|
||||
if (EC_curve_nid2nist(nid) == NULL)
|
||||
return NULL;
|
||||
#endif /* FIPS_MODE */
|
||||
for (i = 0; i < curve_list_length; i++)
|
||||
if (curve_list[i].nid == nid) {
|
||||
ret = ec_group_new_from_data(libctx, curve_list[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
if ((curve = ec_curve_nid2curve(nid)) == NULL
|
||||
|| (ret = ec_group_new_from_data(libctx, *curve)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX, EC_R_UNKNOWN_GROUP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+126
-63
@@ -417,6 +417,120 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.3.3 ECC Full Public-Key Validation.
|
||||
*/
|
||||
int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *point = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 1): Q != infinity */
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(0, EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(eckey->group);
|
||||
if (point == NULL)
|
||||
return 0;
|
||||
|
||||
/* 5.6.2.3.3 (Step 2) Test if the public key is in range */
|
||||
if (!ec_key_public_range_check(ctx, eckey)) {
|
||||
ECerr(0, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(0, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(0, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(0, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
|
||||
* The private key is in the range [1, order-1]
|
||||
*/
|
||||
int ec_key_private_check(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
|
||||
|| BN_cmp(eckey->priv_key, eckey->group->order) >= 0) {
|
||||
ECerr(0, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
|
||||
* Check if generator * priv_key = pub_key
|
||||
*/
|
||||
int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (eckey == NULL
|
||||
|| eckey->group == NULL
|
||||
|| eckey->pub_key == NULL
|
||||
|| eckey->priv_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(eckey->group);
|
||||
if (point == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(0, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.3.3 ECC Full Public-Key Validation
|
||||
@@ -431,81 +545,25 @@ int ec_key_simple_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
if (eckey == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 1): Q != infinity */
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL)
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
if ((point = EC_POINT_new(eckey->group)) == NULL)
|
||||
if (!ec_key_public_check(eckey, ctx))
|
||||
goto err;
|
||||
|
||||
/* 5.6.2.3.3 (Step 2) Test if the public key is in range */
|
||||
if (!ec_key_public_range_check(ctx, eckey)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (eckey->priv_key != NULL) {
|
||||
/*
|
||||
* 5.6.2.1.2 Owner Assurance of Private-Key Validity
|
||||
* The private key is in the range [1, order-1]
|
||||
*/
|
||||
if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
|
||||
|| BN_cmp(eckey->priv_key, order) >= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
if (!ec_key_private_check(eckey)
|
||||
|| !ec_key_pairwise_check(eckey, ctx))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
|
||||
* Check if generator * priv_key = pub_key
|
||||
*/
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
|
||||
NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -569,6 +627,11 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
|
||||
}
|
||||
|
||||
OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *key)
|
||||
{
|
||||
return key->libctx;
|
||||
}
|
||||
|
||||
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
|
||||
{
|
||||
return key->group;
|
||||
|
||||
+29
-23
@@ -599,12 +599,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *ctx_new = NULL;
|
||||
|
||||
if (ctx == NULL)
|
||||
ctx_new = ctx = BN_CTX_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
/* compare the field types */
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
|
||||
@@ -617,6 +612,13 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
|
||||
return 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx_new = ctx = BN_CTX_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
a1 = BN_CTX_get(ctx);
|
||||
a2 = BN_CTX_get(ctx);
|
||||
@@ -1047,7 +1049,24 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t i = 0;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if (!ec_point_is_compat(r, group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (scalar == NULL && num == 0)
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_point_is_compat(points[i], group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx = new_ctx = BN_CTX_secure_new();
|
||||
#endif
|
||||
@@ -1056,21 +1075,6 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((scalar == NULL) && (num == 0)) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
if (!ec_point_is_compat(r, group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_point_is_compat(points[i], group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (group->meth->mul != NULL)
|
||||
ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);
|
||||
else
|
||||
@@ -1183,16 +1187,18 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
||||
int ret = 0;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if (group->mont_data == NULL)
|
||||
return 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx = new_ctx = BN_CTX_secure_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (group->mont_data == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((e = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -679,10 +679,6 @@ ECDSA_SIG *ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
int ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32]);
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32]);
|
||||
void ED25519_public_from_private(uint8_t out_public_key[32],
|
||||
const uint8_t private_key[32]);
|
||||
|
||||
|
||||
+18
-11
@@ -266,17 +266,10 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Apply coordinate blinding for EC_POINT.
|
||||
*
|
||||
* The underlying EC_METHOD can optionally implement this function:
|
||||
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
goto err;
|
||||
/* ensure input point is in affine coords for ladder step efficiency */
|
||||
if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Initialize the Montgomery ladder */
|
||||
@@ -753,6 +746,20 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
if (r_is_at_infinity) {
|
||||
if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* Apply coordinate blinding for EC_POINT.
|
||||
*
|
||||
* The underlying EC_METHOD can optionally implement this function:
|
||||
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, r, ctx)) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
r_is_at_infinity = 0;
|
||||
} else {
|
||||
if (!EC_POINT_add
|
||||
|
||||
+168
-139
@@ -1381,6 +1381,7 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||
* Since we don't have a Mont structure here, SCA hardening is with blinding.
|
||||
* NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.)
|
||||
*/
|
||||
int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *ctx)
|
||||
@@ -1441,112 +1442,133 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
||||
temp = BN_CTX_get(ctx);
|
||||
if (temp == NULL) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* make sure lambda is not zero */
|
||||
/*-
|
||||
* Make sure lambda is not zero.
|
||||
* If the RNG fails, we cannot blind but nevertheless want
|
||||
* code to continue smoothly and not clobber the error stack.
|
||||
*/
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(lambda, group->field, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
ERR_set_mark();
|
||||
ret = BN_priv_rand_range_ex(lambda, group->field, ctx);
|
||||
ERR_pop_to_mark();
|
||||
if (ret == 0) {
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
} while (BN_is_zero(lambda));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->X, p->X, temp, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, temp, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto err;
|
||||
p->Z_is_one = 0;
|
||||
if ((group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)
|
||||
|| !group->meth->field_sqr(group, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->X, p->X, temp, ctx)
|
||||
|| !group->meth->field_mul(group, temp, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto end;
|
||||
|
||||
p->Z_is_one = 0;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
end:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Set s := p, r := 2p.
|
||||
* Input:
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := p, r := 2p: blinded projective (homogeneous) coordinates
|
||||
*
|
||||
* For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve
|
||||
* multiplication resistant against side channel attacks" appendix, as described
|
||||
* at
|
||||
* multiplication resistant against side channel attacks" appendix, described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2
|
||||
* simplified for Z1=1.
|
||||
*
|
||||
* The input point p will be in randomized Jacobian projective coords:
|
||||
* x = X/Z**2, y=Y/Z**3
|
||||
*
|
||||
* The output points p, s, and r are converted to standard (homogeneous)
|
||||
* projective coords:
|
||||
* x = X/Z, y=Y/Z
|
||||
* Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z)
|
||||
* for any non-zero \lambda that holds for projective (homogeneous) coords.
|
||||
*/
|
||||
int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
|
||||
|
||||
t1 = r->Z;
|
||||
t2 = r->Y;
|
||||
t1 = s->Z;
|
||||
t2 = r->Z;
|
||||
t3 = s->X;
|
||||
t4 = r->X;
|
||||
t5 = s->Y;
|
||||
t6 = s->Z;
|
||||
|
||||
/* convert p: (X,Y,Z) -> (XZ,Y,Z**3) */
|
||||
if (!group->meth->field_mul(group, p->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, t1, ctx)
|
||||
/* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t2, p->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t3, group->a, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t2, t4, group->field)
|
||||
|| !BN_mod_add_quick(t2, t2, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t3, group->b, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t1, t6, ctx)
|
||||
|| !BN_mod_lshift_quick(t4, t4, 3, group->field)
|
||||
if (!p->Z_is_one /* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t3, p->X, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t3, group->a, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t5, p->X, group->b, ctx)
|
||||
|| !BN_mod_lshift_quick(t5, t5, 3, group->field)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t3, t6, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t2, group->field)
|
||||
|| !BN_mod_sub_quick(r->X, t4, t5, group->field)
|
||||
|| !BN_mod_add_quick(t1, t3, group->a, group->field)
|
||||
|| !group->meth->field_mul(group, t2, p->X, t1, ctx)
|
||||
|| !BN_mod_add_quick(t2, group->b, t2, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_lshift_quick(r->Z, t1, 2, group->field)
|
||||
|| !EC_POINT_copy(s, p))
|
||||
|| !BN_mod_lshift_quick(r->Z, t2, 2, group->field))
|
||||
return 0;
|
||||
|
||||
/* make sure lambda (r->Y here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(r->Y, group->field, ctx))
|
||||
return 0;
|
||||
} while (BN_is_zero(r->Y));
|
||||
|
||||
/* make sure lambda (s->Z here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(s->Z, group->field, ctx))
|
||||
return 0;
|
||||
} while (BN_is_zero(s->Z));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& (!group->meth->field_encode(group, r->Y, r->Y, ctx)
|
||||
|| !group->meth->field_encode(group, s->Z, s->Z, ctx)))
|
||||
return 0;
|
||||
|
||||
/* blind r and s independently */
|
||||
if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, r->X, r->X, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */
|
||||
return 0;
|
||||
|
||||
r->Z_is_one = 0;
|
||||
s->Z_is_one = 0;
|
||||
p->Z_is_one = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := r + s, r := 2r: projective (homogeneous) coordinates
|
||||
*
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* "A fast parallel elliptic curve multiplication resistant against side channel
|
||||
* attacks", as described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-4
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4
|
||||
*/
|
||||
int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7 = NULL;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
t0 = BN_CTX_get(ctx);
|
||||
@@ -1556,50 +1578,47 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
t4 = BN_CTX_get(ctx);
|
||||
t5 = BN_CTX_get(ctx);
|
||||
t6 = BN_CTX_get(ctx);
|
||||
t7 = BN_CTX_get(ctx);
|
||||
|
||||
if (t7 == NULL
|
||||
|| !group->meth->field_mul(group, t0, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t1, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->X, s->Z, ctx)
|
||||
if (t6 == NULL
|
||||
|| !group->meth->field_mul(group, t6, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, r->X, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t3, r->Z, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t4, group->a, t1, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t4, group->field)
|
||||
|| !BN_mod_add_quick(t4, t3, t2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t4, t0, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_lshift_quick(t7, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t7, t1, ctx)
|
||||
|| !BN_mod_lshift1_quick(t0, t0, group->field)
|
||||
|| !BN_mod_add_quick(t0, t1, t0, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t2, t3, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t1, p->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->Z, t0, ctx)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_mul(group, s->Z, p->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t2, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t2, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t5, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t5, t3, group->field)
|
||||
|| !BN_mod_sub_quick(t5, t5, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t7, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t5, group->a, t0, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !BN_mod_add_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t7, t3, t7, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t5, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t6, t5, ctx)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !BN_mod_lshift_quick(t2, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_sqr(group, s->Z, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t4, s->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t5, group->field)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t5, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t1, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_sub_quick(t1, t1, t4, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t1, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t3, t0, group->field)
|
||||
|| !BN_mod_add_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t4, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t1, t3, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, t1, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_add_quick(r->Z, t7, t5, group->field))
|
||||
|| !BN_mod_add_quick(r->Z, t4, t1, group->field))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
@@ -1610,17 +1629,23 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
/*-
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in projective
|
||||
* coordinates and return r in Jacobian projective coordinates.
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2*Z1;
|
||||
* Y4 = two*b*Z3*SQR(Z2*Z1) + Z3*(a*Z2*Z1+X1*X2)*(X1*Z2+X2*Z1) - X3*SQR(X1*Z2-X2*Z1);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2)*Z1;
|
||||
* Output:
|
||||
* - r := (x,y): affine coordinates
|
||||
*
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in mixed
|
||||
* projective coords, i.e. p is affine and (r,s) in projective (homogeneous)
|
||||
* coords, and return r in affine coordinates.
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2;
|
||||
* Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2);
|
||||
*
|
||||
* Z4 != 0 because:
|
||||
* - Z1==0 implies p is at infinity, which would have caused an early exit in
|
||||
* the caller;
|
||||
* - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch);
|
||||
* - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch);
|
||||
* - Y1==0 implies p has order 2, so either r or s are infinity and handled by
|
||||
@@ -1637,11 +1662,7 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
if (BN_is_zero(s->Z)) {
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
if (!group->meth->field_mul(group, r->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, p->Y, r->Z, ctx)
|
||||
|| !BN_copy(r->Z, p->Z)
|
||||
if (!EC_POINT_copy(r, p)
|
||||
|| !EC_POINT_invert(group, r, ctx))
|
||||
return 0;
|
||||
return 1;
|
||||
@@ -1657,38 +1678,46 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
||||
t6 = BN_CTX_get(ctx);
|
||||
|
||||
if (t6 == NULL
|
||||
|| !BN_mod_lshift1_quick(t0, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t1, r->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t2, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t4, t2, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t2, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->X, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t2, t6, t1, group->field)
|
||||
|| !group->meth->field_mul(group, t5, t5, t2, ctx)
|
||||
|| !BN_mod_sub_quick(t6, t6, t1, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t6, s->X, ctx)
|
||||
|| !BN_mod_add_quick(t4, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, s->Z, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, p->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, r->Z, t0, ctx)
|
||||
/* t3 := X, t4 := Y */
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
|| !group->meth->field_mul(group, r->X, t3, r->Z, ctx)
|
||||
|| !BN_mod_lshift1_quick(t4, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->X, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t6, s->Z, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->Z, t6, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t4, t3, ctx))
|
||||
|| !group->meth->field_mul(group, t2, t3, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, r->X, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t6, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->X, r->Z, ctx)
|
||||
|| !BN_mod_add_quick(t6, r->X, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t6, t6, t1, ctx)
|
||||
|| !BN_mod_add_quick(t6, t6, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t0, t0, r->X, group->field)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t0, s->X, ctx)
|
||||
|| !BN_mod_sub_quick(t0, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t3, t1, ctx)
|
||||
|| (group->meth->field_decode != NULL
|
||||
&& !group->meth->field_decode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_inv(group, t1, t1, ctx)
|
||||
|| (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_mul(group, r->X, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t0, t1, ctx))
|
||||
goto err;
|
||||
|
||||
if (group->meth->field_set_to_one != NULL) {
|
||||
if (!group->meth->field_set_to_one(group, r->Z, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_one(r->Z))
|
||||
goto err;
|
||||
}
|
||||
|
||||
r->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2020 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 <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "crypto/ecx.h"
|
||||
#include "ecx_backend.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
|
||||
int include_private)
|
||||
{
|
||||
size_t privkeylen = 0, pubkeylen;
|
||||
const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
|
||||
unsigned char *pubkey;
|
||||
|
||||
if (ecx == NULL)
|
||||
return 0;
|
||||
|
||||
param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (include_private)
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
/*
|
||||
* If a private key is present then a public key must also be present.
|
||||
* Alternatively we've just got a public key.
|
||||
*/
|
||||
if (param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if (param_priv_key != NULL
|
||||
&& !OSSL_PARAM_get_octet_string(param_priv_key,
|
||||
(void **)&ecx->privkey, ecx->keylen,
|
||||
&privkeylen))
|
||||
return 0;
|
||||
|
||||
pubkey = ecx->pubkey;
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub_key,
|
||||
(void **)&pubkey,
|
||||
sizeof(ecx->pubkey), &pubkeylen))
|
||||
return 0;
|
||||
|
||||
if (pubkeylen != ecx->keylen
|
||||
|| (param_priv_key != NULL && privkeylen != ecx->keylen))
|
||||
return 0;
|
||||
|
||||
ecx->haspubkey = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2020 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
|
||||
*/
|
||||
|
||||
#define ISX448(id) ((id) == EVP_PKEY_X448)
|
||||
#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
|
||||
#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
|
||||
: ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
|
||||
: ED448_KEYLEN))
|
||||
#define KEYNID2TYPE(id) \
|
||||
(IS25519(id) ? ECX_KEY_TYPE_X25519 \
|
||||
: ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
|
||||
: ((id) == EVP_PKEY_ED25519 ? ECX_KEY_TYPE_ED25519 \
|
||||
: ECX_KEY_TYPE_ED448)))
|
||||
#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
|
||||
+16
-2
@@ -10,7 +10,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include "crypto/ecx.h"
|
||||
|
||||
ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
|
||||
ECX_KEY *ecx_key_new(ECX_KEY_TYPE type, int haspubkey)
|
||||
{
|
||||
ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
@@ -18,7 +18,21 @@ ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
|
||||
return NULL;
|
||||
|
||||
ret->haspubkey = haspubkey;
|
||||
ret->keylen = keylen;
|
||||
switch (type) {
|
||||
case ECX_KEY_TYPE_X25519:
|
||||
ret->keylen = X25519_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_X448:
|
||||
ret->keylen = X448_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_ED25519:
|
||||
ret->keylen = ED25519_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_ED448:
|
||||
ret->keylen = ED448_KEYLEN;
|
||||
break;
|
||||
}
|
||||
ret->type = type;
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
|
||||
+72
-27
@@ -19,20 +19,13 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/ecx.h"
|
||||
#include "ec_local.h"
|
||||
#include "curve448/curve448_local.h"
|
||||
|
||||
#define ISX448(id) ((id) == EVP_PKEY_X448)
|
||||
#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
|
||||
#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
|
||||
: ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
|
||||
: ED448_KEYLEN))
|
||||
#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
|
||||
|
||||
#include "ecx_backend.h"
|
||||
|
||||
typedef enum {
|
||||
KEY_OP_PUBLIC,
|
||||
@@ -65,7 +58,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
|
||||
}
|
||||
}
|
||||
|
||||
key = ecx_key_new(KEYLENID(id), 1);
|
||||
key = ecx_key_new(KEYNID2TYPE(id), 1);
|
||||
if (key == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
@@ -413,38 +406,67 @@ static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
const ECX_KEY *key = from->pkey.ecx;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
|
||||
OSSL_PARAM *params = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
/* A key must at least have a public part */
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
key->pubkey, key->keylen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
|
||||
if (key->privkey != NULL) {
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
key->privkey, key->keylen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
params = OSSL_PARAM_BLD_to_param(tmpl);
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
err:
|
||||
ossl_param_bld_free(params);
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
|
||||
int keytype)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
|
||||
|
||||
if (ecx == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ecx_key_fromdata(ecx, params, 1)
|
||||
|| !EVP_PKEY_assign(pkey, keytype, ecx)) {
|
||||
ecx_key_free(ecx);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int x25519_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
@@ -487,9 +509,15 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to
|
||||
ecx_pkey_export_to,
|
||||
x25519_import_from
|
||||
};
|
||||
|
||||
static int x448_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_X448);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
EVP_PKEY_X448,
|
||||
EVP_PKEY_X448,
|
||||
@@ -532,7 +560,8 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to
|
||||
ecx_pkey_export_to,
|
||||
x448_import_from
|
||||
};
|
||||
|
||||
static int ecd_size25519(const EVP_PKEY *pkey)
|
||||
@@ -607,6 +636,10 @@ static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ed25519_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
EVP_PKEY_ED25519,
|
||||
@@ -648,8 +681,16 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to,
|
||||
ed25519_import_from
|
||||
};
|
||||
|
||||
static int ed448_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
EVP_PKEY_ED448,
|
||||
EVP_PKEY_ED448,
|
||||
@@ -690,6 +731,9 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to,
|
||||
ed448_import_from
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
@@ -793,7 +837,8 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
|
||||
if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
|
||||
NULL) == 0)
|
||||
return 0;
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
@@ -834,7 +879,7 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
@@ -1100,7 +1145,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
|
||||
if (key == NULL) {
|
||||
@@ -1142,7 +1187,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
|
||||
if (key == NULL) {
|
||||
@@ -1187,7 +1232,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
};
|
||||
unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
|
||||
ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
unsigned int sz;
|
||||
|
||||
@@ -1244,7 +1289,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
|
||||
};
|
||||
unsigned char x_dst[57], buff[114];
|
||||
ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
EVP_MD_CTX *hashctx = NULL;
|
||||
|
||||
|
||||
@@ -282,6 +282,8 @@ ENGINE *ENGINE_by_id(const char *id)
|
||||
ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
ENGINE_load_builtin_engines();
|
||||
|
||||
if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
|
||||
ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
|
||||
@@ -68,7 +68,7 @@ void ERR_add_error_txt(const char *separator, const char *txt)
|
||||
if (separator == NULL)
|
||||
separator = "";
|
||||
if (err == 0)
|
||||
put_error(ERR_LIB_CMP, NULL, 0, "", 0);
|
||||
put_error(ERR_LIB_NONE, NULL, 0, "", 0);
|
||||
|
||||
do {
|
||||
size_t available_len, data_len;
|
||||
@@ -125,7 +125,7 @@ void ERR_add_error_txt(const char *separator, const char *txt)
|
||||
ERR_add_error_data(2, separator, tmp);
|
||||
OPENSSL_free(tmp);
|
||||
}
|
||||
put_error(ERR_LIB_CMP, func, err, file, line);
|
||||
put_error(ERR_GET_LIB(err), func, err, file, line);
|
||||
txt = curr;
|
||||
} else {
|
||||
if (trailing_separator) {
|
||||
|
||||
+52
-8
@@ -291,6 +291,7 @@ CMS_F_CMS_RECEIPTREQUEST_CREATE0:159:CMS_ReceiptRequest_create0
|
||||
CMS_F_CMS_RECEIPT_VERIFY:160:cms_Receipt_verify
|
||||
CMS_F_CMS_RECIPIENTINFO_DECRYPT:134:CMS_RecipientInfo_decrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_ENCRYPT:169:CMS_RecipientInfo_encrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT:188:
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT:178:cms_RecipientInfo_kari_encrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG:175:CMS_RecipientInfo_kari_get0_alg
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID:173:\
|
||||
@@ -1310,6 +1311,7 @@ SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:*
|
||||
SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\
|
||||
ossl_statem_server_post_process_message
|
||||
SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work
|
||||
SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:
|
||||
SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message
|
||||
SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition
|
||||
SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\
|
||||
@@ -1769,6 +1771,7 @@ X509V3_F_DO_DIRNAME:144:do_dirname
|
||||
X509V3_F_DO_EXT_I2D:135:do_ext_i2d
|
||||
X509V3_F_DO_EXT_NCONF:151:do_ext_nconf
|
||||
X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname
|
||||
X509V3_F_I2R_ISSUER_SIGN_TOOL:176:
|
||||
X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED
|
||||
X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING
|
||||
X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER
|
||||
@@ -1808,6 +1811,7 @@ X509V3_F_V2I_GENERAL_NAME_EX:117:v2i_GENERAL_NAME_ex
|
||||
X509V3_F_V2I_IDP:157:v2i_idp
|
||||
X509V3_F_V2I_IPADDRBLOCKS:159:v2i_IPAddrBlocks
|
||||
X509V3_F_V2I_ISSUER_ALT:153:v2i_issuer_alt
|
||||
X509V3_F_V2I_ISSUER_SIGN_TOOL:175:
|
||||
X509V3_F_V2I_NAME_CONSTRAINTS:147:v2i_NAME_CONSTRAINTS
|
||||
X509V3_F_V2I_POLICY_CONSTRAINTS:146:v2i_POLICY_CONSTRAINTS
|
||||
X509V3_F_V2I_POLICY_MAPPINGS:145:v2i_POLICY_MAPPINGS
|
||||
@@ -2075,17 +2079,28 @@ BN_R_P_IS_NOT_PRIME:112:p is not prime
|
||||
BN_R_TOO_MANY_ITERATIONS:113:too many iterations
|
||||
BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables
|
||||
CMP_R_ALGORITHM_NOT_SUPPORTED:139:algorithm not supported
|
||||
CMP_R_BAD_CHECKAFTER_IN_POLLREP:167:bad checkafter in pollrep
|
||||
CMP_R_BAD_REQUEST_ID:108:bad request id
|
||||
CMP_R_CERTHASH_UNMATCHED:156:certhash unmatched
|
||||
CMP_R_CERTID_NOT_FOUND:109:certid not found
|
||||
CMP_R_CERTIFICATE_NOT_ACCEPTED:169:certificate not accepted
|
||||
CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found
|
||||
CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found
|
||||
CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found
|
||||
CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match
|
||||
CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range
|
||||
CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE:166:checking pbm no secret available
|
||||
CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning
|
||||
CMP_R_ENCOUNTERED_WAITING:162:encountered waiting
|
||||
CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection
|
||||
CMP_R_ERROR_CREATING_CERTCONF:116:error creating certconf
|
||||
CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep
|
||||
CMP_R_ERROR_CREATING_CR:163:error creating cr
|
||||
CMP_R_ERROR_CREATING_ERROR:118:error creating error
|
||||
CMP_R_ERROR_CREATING_GENM:119:error creating genm
|
||||
CMP_R_ERROR_CREATING_GENP:120:error creating genp
|
||||
CMP_R_ERROR_CREATING_IR:164:error creating ir
|
||||
CMP_R_ERROR_CREATING_KUR:165:error creating kur
|
||||
CMP_R_ERROR_CREATING_P10CR:121:error creating p10cr
|
||||
CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf
|
||||
CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep
|
||||
@@ -2093,8 +2108,10 @@ CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq
|
||||
CMP_R_ERROR_CREATING_RP:125:error creating rp
|
||||
CMP_R_ERROR_CREATING_RR:126:error creating rr
|
||||
CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus
|
||||
CMP_R_ERROR_PROCESSING_MESSAGE:158:error processing message
|
||||
CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
|
||||
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
|
||||
CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
|
||||
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
@@ -2107,29 +2124,41 @@ CMP_R_MISSING_PRIVATE_KEY:131:missing private key
|
||||
CMP_R_MISSING_PROTECTION:143:missing protection
|
||||
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
|
||||
CMP_R_MISSING_TRUST_STORE:144:missing trust store
|
||||
CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED:161:multiple requests not supported
|
||||
CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED:170:multiple responses not supported
|
||||
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
|
||||
CMP_R_NO_STDIO:194:no stdio
|
||||
CMP_R_NO_SUITABLE_SENDER_CERT:145:no suitable sender cert
|
||||
CMP_R_NULL_ARGUMENT:103:null argument
|
||||
CMP_R_PKIBODY_ERROR:146:pkibody error
|
||||
CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found
|
||||
CMP_R_POLLING_FAILED:172:polling failed
|
||||
CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate
|
||||
CMP_R_RECEIVED_ERROR:180:received error
|
||||
CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched
|
||||
CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted
|
||||
CMP_R_REQUEST_REJECTED_BY_SERVER:182:request rejected by server
|
||||
CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED:150:\
|
||||
sender generalname type not supported
|
||||
CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG:151:srvcert does not validate msg
|
||||
CMP_R_TOTAL_TIMEOUT:184:total timeout
|
||||
CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
|
||||
CMP_R_TRANSFER_ERROR:159:transfer error
|
||||
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
|
||||
CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
|
||||
CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
|
||||
CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
|
||||
CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
|
||||
CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus
|
||||
CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
|
||||
CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
|
||||
CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
|
||||
unsupported protection alg dhbasedmac
|
||||
CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid
|
||||
CMP_R_WRONG_CERTID_IN_RP:187:wrong certid in rp
|
||||
CMP_R_WRONG_PBM_VALUE:155:wrong pbm value
|
||||
CMP_R_WRONG_RP_COMPONENT_COUNT:188:wrong rp component count
|
||||
CMP_R_WRONG_SERIAL_IN_RP:173:wrong serial in rp
|
||||
CMS_R_ADD_SIGNER_ERROR:99:add signer error
|
||||
CMS_R_ATTRIBUTE_ERROR:161:attribute error
|
||||
CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present
|
||||
@@ -2256,6 +2285,11 @@ CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random
|
||||
CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
|
||||
CRMF_R_MALFORMED_IV:101:malformed iv
|
||||
CRMF_R_NULL_ARGUMENT:109:null argument
|
||||
CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
|
||||
CRMF_R_POPO_MISSING:121:popo missing
|
||||
CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
|
||||
CRMF_R_POPO_MISSING_SUBJECT:119:popo missing subject
|
||||
CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted
|
||||
CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure
|
||||
CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure
|
||||
CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm
|
||||
@@ -2264,7 +2298,6 @@ CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher
|
||||
CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
|
||||
unsupported method for creating popo
|
||||
CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method
|
||||
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted
|
||||
CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name
|
||||
CRYPTO_R_CONFLICTING_NAMES:118:conflicting names
|
||||
CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
|
||||
@@ -2489,10 +2522,13 @@ EVP_R_EXPECTING_A_DSA_KEY:129:expecting a dsa key
|
||||
EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key
|
||||
EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key
|
||||
EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key
|
||||
EVP_R_FETCH_FAILED:202:fetch failed
|
||||
EVP_R_FINAL_ERROR:188:final error
|
||||
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
|
||||
EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
|
||||
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
|
||||
EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS:204:inaccessible domain parameters
|
||||
EVP_R_INACCESSIBLE_KEY:203:inaccessible key
|
||||
EVP_R_INITIALIZATION_ERROR:134:initialization error
|
||||
EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
|
||||
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
|
||||
@@ -2505,6 +2541,7 @@ EVP_R_INVALID_OPERATION:148:invalid operation
|
||||
EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions
|
||||
EVP_R_INVALID_SALT_LENGTH:186:invalid salt length
|
||||
EVP_R_KEYGEN_FAILURE:120:keygen failure
|
||||
EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure
|
||||
EVP_R_KEY_SETUP_FAILED:180:key setup failed
|
||||
EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
|
||||
EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null
|
||||
@@ -2515,6 +2552,7 @@ EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length
|
||||
EVP_R_NO_CIPHER_SET:131:no cipher set
|
||||
EVP_R_NO_DEFAULT_DIGEST:158:no default digest
|
||||
EVP_R_NO_DIGEST_SET:139:no digest set
|
||||
EVP_R_NO_IMPORT_FUNCTION:206:no import function
|
||||
EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available
|
||||
EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present
|
||||
EVP_R_NO_KEY_SET:154:no key set
|
||||
@@ -2534,6 +2572,7 @@ EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
|
||||
EVP_R_TOO_MANY_RECORDS:183:too many records
|
||||
EVP_R_UNKNOWN_CIPHER:160:unknown cipher
|
||||
EVP_R_UNKNOWN_DIGEST:161:unknown digest
|
||||
EVP_R_UNKNOWN_KEY_TYPE:207:unknown key type
|
||||
EVP_R_UNKNOWN_OPTION:169:unknown option
|
||||
EVP_R_UNKNOWN_PBE_ALGORITHM:121:unknown pbe algorithm
|
||||
EVP_R_UNSUPPORTED_ALGORITHM:156:unsupported algorithm
|
||||
@@ -2563,12 +2602,13 @@ HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
||||
HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location
|
||||
HTTP_R_RECEIVED_ERROR:105:received error
|
||||
HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version
|
||||
HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
|
||||
HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
|
||||
HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
|
||||
HTTP_R_SERVER_RESPONSE_PARSE_ERROR:104:server response parse error
|
||||
HTTP_R_SERVER_SENT_ERROR:105:server sent error
|
||||
HTTP_R_SERVER_SENT_WRONG_HTTP_VERSION:106:server sent wrong http version
|
||||
HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
|
||||
HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
|
||||
HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported
|
||||
HTTP_R_TLS_NOT_ENABLED:107:tls not enabled
|
||||
HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections
|
||||
@@ -2773,11 +2813,13 @@ PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt
|
||||
PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
|
||||
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
|
||||
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
|
||||
PROV_R_FAILED_TO_SIGN:175:failed to sign
|
||||
PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\
|
||||
illegal or unsupported padding mode
|
||||
PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length
|
||||
PROV_R_INVALID_AAD:108:invalid aad
|
||||
PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length
|
||||
PROV_R_INVALID_CURVE:176:invalid curve
|
||||
PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
|
||||
PROV_R_INVALID_DATA:115:invalid data
|
||||
PROV_R_INVALID_DIGEST:122:invalid digest
|
||||
@@ -2817,6 +2859,7 @@ PROV_R_MISSING_XCGHASH:135:missing xcghash
|
||||
PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
PROV_R_NO_PARAMETERS_SET:177:no parameters set
|
||||
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
|
||||
PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
|
||||
PROV_R_READ_KEY:159:read key
|
||||
@@ -2970,6 +3013,7 @@ SM2_R_INVALID_ENCODING:104:invalid encoding
|
||||
SM2_R_INVALID_FIELD:105:invalid field
|
||||
SM2_R_NO_PARAMETERS_SET:109:no parameters set
|
||||
SM2_R_USER_ID_TOO_LARGE:106:user id too large
|
||||
SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed
|
||||
SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY:291:\
|
||||
application data after close notify
|
||||
SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake
|
||||
@@ -3126,8 +3170,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key
|
||||
SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key
|
||||
SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\
|
||||
mixed handshake and non handshake data
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:295:mixed special operator with groups
|
||||
SSL_R_NESTED_GROUP:296:nested group
|
||||
SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups
|
||||
SSL_R_NESTED_GROUP:297:nested group
|
||||
SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary
|
||||
SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate
|
||||
SSL_R_NOT_SERVER:284:not server
|
||||
@@ -3235,9 +3279,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines
|
||||
SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message
|
||||
SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data
|
||||
SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading
|
||||
SSL_R_UNEXPECTED_GROUP_CLOSE:297:unexpected group close
|
||||
SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close
|
||||
SSL_R_UNEXPECTED_MESSAGE:244:unexpected message
|
||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:299:unexpected operator in group
|
||||
SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group
|
||||
SSL_R_UNEXPECTED_RECORD:245:unexpected record
|
||||
SSL_R_UNINITIALIZED:276:uninitialized
|
||||
SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type
|
||||
|
||||
@@ -291,6 +291,7 @@ CMS_F_CMS_RECEIPTREQUEST_CREATE0:159:CMS_ReceiptRequest_create0
|
||||
CMS_F_CMS_RECEIPT_VERIFY:160:cms_Receipt_verify
|
||||
CMS_F_CMS_RECIPIENTINFO_DECRYPT:134:CMS_RecipientInfo_decrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_ENCRYPT:169:CMS_RecipientInfo_encrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_DECRYPT:188:
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT:178:cms_RecipientInfo_kari_encrypt
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG:175:CMS_RecipientInfo_kari_get0_alg
|
||||
CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID:173:\
|
||||
@@ -1310,6 +1311,7 @@ SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE:431:*
|
||||
SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE:601:\
|
||||
ossl_statem_server_post_process_message
|
||||
SSL_F_OSSL_STATEM_SERVER_POST_WORK:602:ossl_statem_server_post_work
|
||||
SSL_F_OSSL_STATEM_SERVER_PRE_WORK:640:
|
||||
SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE:603:ossl_statem_server_process_message
|
||||
SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION:418:ossl_statem_server_read_transition
|
||||
SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION:604:\
|
||||
@@ -1769,6 +1771,7 @@ X509V3_F_DO_DIRNAME:144:do_dirname
|
||||
X509V3_F_DO_EXT_I2D:135:do_ext_i2d
|
||||
X509V3_F_DO_EXT_NCONF:151:do_ext_nconf
|
||||
X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname
|
||||
X509V3_F_I2R_ISSUER_SIGN_TOOL:176:
|
||||
X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED
|
||||
X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING
|
||||
X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER
|
||||
@@ -1808,6 +1811,7 @@ X509V3_F_V2I_GENERAL_NAME_EX:117:v2i_GENERAL_NAME_ex
|
||||
X509V3_F_V2I_IDP:157:v2i_idp
|
||||
X509V3_F_V2I_IPADDRBLOCKS:159:v2i_IPAddrBlocks
|
||||
X509V3_F_V2I_ISSUER_ALT:153:v2i_issuer_alt
|
||||
X509V3_F_V2I_ISSUER_SIGN_TOOL:175:
|
||||
X509V3_F_V2I_NAME_CONSTRAINTS:147:v2i_NAME_CONSTRAINTS
|
||||
X509V3_F_V2I_POLICY_CONSTRAINTS:146:v2i_POLICY_CONSTRAINTS
|
||||
X509V3_F_V2I_POLICY_MAPPINGS:145:v2i_POLICY_MAPPINGS
|
||||
@@ -2075,17 +2079,28 @@ BN_R_P_IS_NOT_PRIME:112:p is not prime
|
||||
BN_R_TOO_MANY_ITERATIONS:113:too many iterations
|
||||
BN_R_TOO_MANY_TEMPORARY_VARIABLES:109:too many temporary variables
|
||||
CMP_R_ALGORITHM_NOT_SUPPORTED:139:algorithm not supported
|
||||
CMP_R_BAD_CHECKAFTER_IN_POLLREP:167:bad checkafter in pollrep
|
||||
CMP_R_BAD_REQUEST_ID:108:bad request id
|
||||
CMP_R_CERTHASH_UNMATCHED:156:certhash unmatched
|
||||
CMP_R_CERTID_NOT_FOUND:109:certid not found
|
||||
CMP_R_CERTIFICATE_NOT_ACCEPTED:169:certificate not accepted
|
||||
CMP_R_CERTIFICATE_NOT_FOUND:112:certificate not found
|
||||
CMP_R_CERTREQMSG_NOT_FOUND:157:certreqmsg not found
|
||||
CMP_R_CERTRESPONSE_NOT_FOUND:113:certresponse not found
|
||||
CMP_R_CERT_AND_KEY_DO_NOT_MATCH:114:cert and key do not match
|
||||
CMP_R_CHECKAFTER_OUT_OF_RANGE:181:checkafter out of range
|
||||
CMP_R_CHECKING_PBM_NO_SECRET_AVAILABLE:166:checking pbm no secret available
|
||||
CMP_R_ENCOUNTERED_KEYUPDATEWARNING:176:encountered keyupdatewarning
|
||||
CMP_R_ENCOUNTERED_WAITING:162:encountered waiting
|
||||
CMP_R_ERROR_CALCULATING_PROTECTION:115:error calculating protection
|
||||
CMP_R_ERROR_CREATING_CERTCONF:116:error creating certconf
|
||||
CMP_R_ERROR_CREATING_CERTREP:117:error creating certrep
|
||||
CMP_R_ERROR_CREATING_CR:163:error creating cr
|
||||
CMP_R_ERROR_CREATING_ERROR:118:error creating error
|
||||
CMP_R_ERROR_CREATING_GENM:119:error creating genm
|
||||
CMP_R_ERROR_CREATING_GENP:120:error creating genp
|
||||
CMP_R_ERROR_CREATING_IR:164:error creating ir
|
||||
CMP_R_ERROR_CREATING_KUR:165:error creating kur
|
||||
CMP_R_ERROR_CREATING_P10CR:121:error creating p10cr
|
||||
CMP_R_ERROR_CREATING_PKICONF:122:error creating pkiconf
|
||||
CMP_R_ERROR_CREATING_POLLREP:123:error creating pollrep
|
||||
@@ -2093,8 +2108,10 @@ CMP_R_ERROR_CREATING_POLLREQ:124:error creating pollreq
|
||||
CMP_R_ERROR_CREATING_RP:125:error creating rp
|
||||
CMP_R_ERROR_CREATING_RR:126:error creating rr
|
||||
CMP_R_ERROR_PARSING_PKISTATUS:107:error parsing pkistatus
|
||||
CMP_R_ERROR_PROCESSING_MESSAGE:158:error processing message
|
||||
CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message
|
||||
CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash
|
||||
CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf
|
||||
CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection
|
||||
CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey
|
||||
CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random
|
||||
@@ -2107,29 +2124,41 @@ CMP_R_MISSING_PRIVATE_KEY:131:missing private key
|
||||
CMP_R_MISSING_PROTECTION:143:missing protection
|
||||
CMP_R_MISSING_SENDER_IDENTIFICATION:111:missing sender identification
|
||||
CMP_R_MISSING_TRUST_STORE:144:missing trust store
|
||||
CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED:161:multiple requests not supported
|
||||
CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED:170:multiple responses not supported
|
||||
CMP_R_MULTIPLE_SAN_SOURCES:102:multiple san sources
|
||||
CMP_R_NO_STDIO:194:no stdio
|
||||
CMP_R_NO_SUITABLE_SENDER_CERT:145:no suitable sender cert
|
||||
CMP_R_NULL_ARGUMENT:103:null argument
|
||||
CMP_R_PKIBODY_ERROR:146:pkibody error
|
||||
CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found
|
||||
CMP_R_POLLING_FAILED:172:polling failed
|
||||
CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate
|
||||
CMP_R_RECEIVED_ERROR:180:received error
|
||||
CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched
|
||||
CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted
|
||||
CMP_R_REQUEST_REJECTED_BY_SERVER:182:request rejected by server
|
||||
CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED:150:\
|
||||
sender generalname type not supported
|
||||
CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG:151:srvcert does not validate msg
|
||||
CMP_R_TOTAL_TIMEOUT:184:total timeout
|
||||
CMP_R_TRANSACTIONID_UNMATCHED:152:transactionid unmatched
|
||||
CMP_R_TRANSFER_ERROR:159:transfer error
|
||||
CMP_R_UNEXPECTED_PKIBODY:133:unexpected pkibody
|
||||
CMP_R_UNEXPECTED_PKISTATUS:185:unexpected pkistatus
|
||||
CMP_R_UNEXPECTED_PVNO:153:unexpected pvno
|
||||
CMP_R_UNKNOWN_ALGORITHM_ID:134:unknown algorithm id
|
||||
CMP_R_UNKNOWN_CERT_TYPE:135:unknown cert type
|
||||
CMP_R_UNKNOWN_PKISTATUS:186:unknown pkistatus
|
||||
CMP_R_UNSUPPORTED_ALGORITHM:136:unsupported algorithm
|
||||
CMP_R_UNSUPPORTED_KEY_TYPE:137:unsupported key type
|
||||
CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC:154:\
|
||||
unsupported protection alg dhbasedmac
|
||||
CMP_R_WRONG_ALGORITHM_OID:138:wrong algorithm oid
|
||||
CMP_R_WRONG_CERTID_IN_RP:187:wrong certid in rp
|
||||
CMP_R_WRONG_PBM_VALUE:155:wrong pbm value
|
||||
CMP_R_WRONG_RP_COMPONENT_COUNT:188:wrong rp component count
|
||||
CMP_R_WRONG_SERIAL_IN_RP:173:wrong serial in rp
|
||||
CMS_R_ADD_SIGNER_ERROR:99:add signer error
|
||||
CMS_R_ATTRIBUTE_ERROR:161:attribute error
|
||||
CMS_R_CERTIFICATE_ALREADY_PRESENT:175:certificate already present
|
||||
@@ -2256,6 +2285,11 @@ CRMF_R_FAILURE_OBTAINING_RANDOM:107:failure obtaining random
|
||||
CRMF_R_ITERATIONCOUNT_BELOW_100:108:iterationcount below 100
|
||||
CRMF_R_MALFORMED_IV:101:malformed iv
|
||||
CRMF_R_NULL_ARGUMENT:109:null argument
|
||||
CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY:117:popo inconsistent public key
|
||||
CRMF_R_POPO_MISSING:121:popo missing
|
||||
CRMF_R_POPO_MISSING_PUBLIC_KEY:118:popo missing public key
|
||||
CRMF_R_POPO_MISSING_SUBJECT:119:popo missing subject
|
||||
CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED:120:popo raverified not accepted
|
||||
CRMF_R_SETTING_MAC_ALGOR_FAILURE:110:setting mac algor failure
|
||||
CRMF_R_SETTING_OWF_ALGOR_FAILURE:111:setting owf algor failure
|
||||
CRMF_R_UNSUPPORTED_ALGORITHM:112:unsupported algorithm
|
||||
@@ -2264,7 +2298,6 @@ CRMF_R_UNSUPPORTED_CIPHER:114:unsupported cipher
|
||||
CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO:115:\
|
||||
unsupported method for creating popo
|
||||
CRMF_R_UNSUPPORTED_POPO_METHOD:116:unsupported popo method
|
||||
CRMF_R_UNSUPPORTED_POPO_NOT_ACCEPTED:117:unsupported popo not accepted
|
||||
CRYPTO_R_BAD_ALGORITHM_NAME:117:bad algorithm name
|
||||
CRYPTO_R_CONFLICTING_NAMES:118:conflicting names
|
||||
CRYPTO_R_FIPS_MODE_NOT_SUPPORTED:101:fips mode not supported
|
||||
@@ -2489,10 +2522,13 @@ EVP_R_EXPECTING_A_DSA_KEY:129:expecting a dsa key
|
||||
EVP_R_EXPECTING_A_EC_KEY:142:expecting a ec key
|
||||
EVP_R_EXPECTING_A_POLY1305_KEY:164:expecting a poly1305 key
|
||||
EVP_R_EXPECTING_A_SIPHASH_KEY:175:expecting a siphash key
|
||||
EVP_R_FETCH_FAILED:202:fetch failed
|
||||
EVP_R_FINAL_ERROR:188:final error
|
||||
EVP_R_FIPS_MODE_NOT_SUPPORTED:167:fips mode not supported
|
||||
EVP_R_GET_RAW_KEY_FAILED:182:get raw key failed
|
||||
EVP_R_ILLEGAL_SCRYPT_PARAMETERS:171:illegal scrypt parameters
|
||||
EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS:204:inaccessible domain parameters
|
||||
EVP_R_INACCESSIBLE_KEY:203:inaccessible key
|
||||
EVP_R_INITIALIZATION_ERROR:134:initialization error
|
||||
EVP_R_INPUT_NOT_INITIALIZED:111:input not initialized
|
||||
EVP_R_INVALID_CUSTOM_LENGTH:185:invalid custom length
|
||||
@@ -2505,6 +2541,7 @@ EVP_R_INVALID_OPERATION:148:invalid operation
|
||||
EVP_R_INVALID_PROVIDER_FUNCTIONS:193:invalid provider functions
|
||||
EVP_R_INVALID_SALT_LENGTH:186:invalid salt length
|
||||
EVP_R_KEYGEN_FAILURE:120:keygen failure
|
||||
EVP_R_KEYMGMT_EXPORT_FAILURE:205:keymgmt export failure
|
||||
EVP_R_KEY_SETUP_FAILED:180:key setup failed
|
||||
EVP_R_MEMORY_LIMIT_EXCEEDED:172:memory limit exceeded
|
||||
EVP_R_MESSAGE_DIGEST_IS_NULL:159:message digest is null
|
||||
@@ -2515,6 +2552,7 @@ EVP_R_NOT_XOF_OR_INVALID_LENGTH:178:not XOF or invalid length
|
||||
EVP_R_NO_CIPHER_SET:131:no cipher set
|
||||
EVP_R_NO_DEFAULT_DIGEST:158:no default digest
|
||||
EVP_R_NO_DIGEST_SET:139:no digest set
|
||||
EVP_R_NO_IMPORT_FUNCTION:206:no import function
|
||||
EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available
|
||||
EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present
|
||||
EVP_R_NO_KEY_SET:154:no key set
|
||||
@@ -2534,6 +2572,7 @@ EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa
|
||||
EVP_R_TOO_MANY_RECORDS:183:too many records
|
||||
EVP_R_UNKNOWN_CIPHER:160:unknown cipher
|
||||
EVP_R_UNKNOWN_DIGEST:161:unknown digest
|
||||
EVP_R_UNKNOWN_KEY_TYPE:207:unknown key type
|
||||
EVP_R_UNKNOWN_OPTION:169:unknown option
|
||||
EVP_R_UNKNOWN_PBE_ALGORITHM:121:unknown pbe algorithm
|
||||
EVP_R_UNSUPPORTED_ALGORITHM:156:unsupported algorithm
|
||||
@@ -2563,12 +2602,13 @@ HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
||||
HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location
|
||||
HTTP_R_RECEIVED_ERROR:105:received error
|
||||
HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version
|
||||
HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http
|
||||
HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled
|
||||
HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long
|
||||
HTTP_R_SERVER_RESPONSE_PARSE_ERROR:104:server response parse error
|
||||
HTTP_R_SERVER_SENT_ERROR:105:server sent error
|
||||
HTTP_R_SERVER_SENT_WRONG_HTTP_VERSION:106:server sent wrong http version
|
||||
HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error
|
||||
HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported
|
||||
HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported
|
||||
HTTP_R_TLS_NOT_ENABLED:107:tls not enabled
|
||||
HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections
|
||||
@@ -2773,11 +2813,13 @@ PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt
|
||||
PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
|
||||
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
|
||||
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
|
||||
PROV_R_FAILED_TO_SIGN:175:failed to sign
|
||||
PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\
|
||||
illegal or unsupported padding mode
|
||||
PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length
|
||||
PROV_R_INVALID_AAD:108:invalid aad
|
||||
PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length
|
||||
PROV_R_INVALID_CURVE:176:invalid curve
|
||||
PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length
|
||||
PROV_R_INVALID_DATA:115:invalid data
|
||||
PROV_R_INVALID_DIGEST:122:invalid digest
|
||||
@@ -2817,6 +2859,7 @@ PROV_R_MISSING_XCGHASH:135:missing xcghash
|
||||
PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
PROV_R_NO_PARAMETERS_SET:177:no parameters set
|
||||
PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
|
||||
PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small
|
||||
PROV_R_READ_KEY:159:read key
|
||||
@@ -3076,6 +3119,7 @@ SSL_R_EXTENSION_NOT_RECEIVED:279:extension not received
|
||||
SSL_R_EXTRA_DATA_IN_MESSAGE:153:extra data in message
|
||||
SSL_R_EXT_LENGTH_MISMATCH:163:ext length mismatch
|
||||
SSL_R_FAILED_TO_INIT_ASYNC:405:failed to init async
|
||||
SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed
|
||||
SSL_R_FRAGMENTED_CLIENT_HELLO:401:fragmented client hello
|
||||
SSL_R_GOT_A_FIN_BEFORE_A_CCS:154:got a fin before a ccs
|
||||
SSL_R_HTTPS_PROXY_REQUEST:155:https proxy request
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2019-2020 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
|
||||
@@ -59,7 +59,8 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
|
||||
X509_check_purpose(cert, -1, 0);
|
||||
if ((cid = ESS_CERT_ID_new()) == NULL)
|
||||
goto err;
|
||||
X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
|
||||
if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
|
||||
goto err;
|
||||
if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
|
||||
goto err;
|
||||
|
||||
|
||||
+3
-3
@@ -657,12 +657,12 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
|
||||
size_t sz;
|
||||
OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
|
||||
if (ctx == NULL || ctx->digest == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL);
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->digest->prov == NULL)
|
||||
if (ctx->digest != NULL && ctx->digest->prov == NULL)
|
||||
goto legacy;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
@@ -64,12 +64,16 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
"expecting a poly1305 key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY),
|
||||
"expecting a siphash key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FETCH_FAILED), "fetch failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FIPS_MODE_NOT_SUPPORTED),
|
||||
"fips mode not supported"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
|
||||
"illegal scrypt parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS),
|
||||
"inaccessible domain parameters"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_KEY), "inaccessible key"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR),
|
||||
"initialization error"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED),
|
||||
@@ -87,6 +91,8 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH),
|
||||
"invalid salt length"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYGEN_FAILURE), "keygen failure"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE),
|
||||
"keymgmt export failure"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED),
|
||||
"memory limit exceeded"},
|
||||
@@ -102,6 +108,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_IMPORT_FUNCTION), "no import function"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE),
|
||||
"no keymgmt available"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present"},
|
||||
@@ -128,6 +135,7 @@ static const ERR_STRING_DATA EVP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_KEY_TYPE), "unknown key type"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option"},
|
||||
{ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM),
|
||||
"unknown pbe algorithm"},
|
||||
|
||||
+48
-6
@@ -294,9 +294,26 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
return inner_evp_generic_fetch(libctx,
|
||||
operation_id, 0, name, properties,
|
||||
new_method, up_ref_method, free_method);
|
||||
void *ret = inner_evp_generic_fetch(libctx,
|
||||
operation_id, 0, name, properties,
|
||||
new_method, up_ref_method, free_method);
|
||||
|
||||
if (ret == NULL) {
|
||||
int code = EVP_R_FETCH_FAILED;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
ERR_raise(ERR_LIB_EVP, code);
|
||||
#else
|
||||
ERR_raise_data(ERR_LIB_EVP, code,
|
||||
"%s, Algorithm (%s), Properties (%s)",
|
||||
(openssl_ctx_is_default(libctx)
|
||||
? "Default library context"
|
||||
: "Non-default library context"),
|
||||
name = NULL ? "<null>" : name,
|
||||
properties == NULL ? "<null>" : properties);
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -314,9 +331,34 @@ void *evp_generic_fetch_by_number(OPENSSL_CTX *libctx, int operation_id,
|
||||
int (*up_ref_method)(void *),
|
||||
void (*free_method)(void *))
|
||||
{
|
||||
return inner_evp_generic_fetch(libctx,
|
||||
operation_id, name_id, NULL, properties,
|
||||
new_method, up_ref_method, free_method);
|
||||
void *ret = inner_evp_generic_fetch(libctx,
|
||||
operation_id, name_id, NULL,
|
||||
properties, new_method, up_ref_method,
|
||||
free_method);
|
||||
|
||||
if (ret == NULL) {
|
||||
int code = EVP_R_FETCH_FAILED;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
ERR_raise(ERR_LIB_EVP, code);
|
||||
#else
|
||||
{
|
||||
OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
|
||||
const char *name = (namemap == NULL)
|
||||
? NULL
|
||||
: ossl_namemap_num2name(namemap, name_id, 0);
|
||||
|
||||
ERR_raise_data(ERR_LIB_EVP, code,
|
||||
"%s, Algorithm (%s), Properties (%s)",
|
||||
(openssl_ctx_is_default(libctx)
|
||||
? "Default library context"
|
||||
: "Non-default library context"),
|
||||
name = NULL ? "<null>" : name,
|
||||
properties == NULL ? "<null>" : properties);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
|
||||
|
||||
@@ -81,6 +81,16 @@ struct evp_keymgmt_st {
|
||||
OSSL_OP_keymgmt_set_params_fn *set_params;
|
||||
OSSL_OP_keymgmt_settable_params_fn *settable_params;
|
||||
|
||||
/* Generation, a complex constructor */
|
||||
OSSL_OP_keymgmt_gen_init_fn *gen_init;
|
||||
OSSL_OP_keymgmt_gen_set_template_fn *gen_set_template;
|
||||
OSSL_OP_keymgmt_gen_set_params_fn *gen_set_params;
|
||||
OSSL_OP_keymgmt_gen_settable_params_fn *gen_settable_params;
|
||||
OSSL_OP_keymgmt_gen_get_params_fn *gen_get_params;
|
||||
OSSL_OP_keymgmt_gen_gettable_params_fn *gen_gettable_params;
|
||||
OSSL_OP_keymgmt_gen_fn *gen;
|
||||
OSSL_OP_keymgmt_gen_cleanup_fn *gen_cleanup;
|
||||
|
||||
/* Key object checking */
|
||||
OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
|
||||
OSSL_OP_keymgmt_has_fn *has;
|
||||
@@ -129,9 +139,11 @@ struct evp_signature_st {
|
||||
OSSL_OP_signature_digest_sign_init_fn *digest_sign_init;
|
||||
OSSL_OP_signature_digest_sign_update_fn *digest_sign_update;
|
||||
OSSL_OP_signature_digest_sign_final_fn *digest_sign_final;
|
||||
OSSL_OP_signature_digest_sign_fn *digest_sign;
|
||||
OSSL_OP_signature_digest_verify_init_fn *digest_verify_init;
|
||||
OSSL_OP_signature_digest_verify_update_fn *digest_verify_update;
|
||||
OSSL_OP_signature_digest_verify_final_fn *digest_verify_final;
|
||||
OSSL_OP_signature_digest_verify_fn *digest_verify;
|
||||
OSSL_OP_signature_freectx_fn *freectx;
|
||||
OSSL_OP_signature_dupctx_fn *dupctx;
|
||||
OSSL_OP_signature_get_ctx_params_fn *get_ctx_params;
|
||||
|
||||
@@ -197,7 +197,7 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
|
||||
*/
|
||||
ERR_set_mark();
|
||||
|
||||
if (ctx->engine != NULL || ctx->keytype == NULL)
|
||||
if (ctx->keymgmt == NULL)
|
||||
goto legacy;
|
||||
|
||||
/*
|
||||
|
||||
+105
-43
@@ -39,13 +39,26 @@ static int try_import(const OSSL_PARAM params[], void *arg)
|
||||
{
|
||||
struct import_data_st *data = arg;
|
||||
|
||||
/*
|
||||
* It's fine if there was no data to transfer, we just end up with an
|
||||
* empty destination key.
|
||||
*/
|
||||
if (params[0].key == NULL)
|
||||
return 1;
|
||||
|
||||
/* Just in time creation of keydata, if needed */
|
||||
if (data->keydata == NULL
|
||||
&& (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
|
||||
params);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
void *keydata = NULL;
|
||||
struct import_data_st import_data;
|
||||
size_t i = 0;
|
||||
|
||||
@@ -54,7 +67,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
return NULL;
|
||||
|
||||
/* If we have an unassigned key, give up */
|
||||
if (pk->keymgmt == NULL)
|
||||
if (pk->keydata == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If |keymgmt| matches the "origin" |keymgmt|, no more to do */
|
||||
@@ -91,10 +104,6 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
if (!ossl_assert(match_type(pk->keymgmt, keymgmt)))
|
||||
return NULL;
|
||||
|
||||
/* Create space to import data into */
|
||||
if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* We look at the already cached provider keys, and import from the
|
||||
* first that supports it (i.e. use its export function), and export
|
||||
@@ -102,7 +111,7 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
*/
|
||||
|
||||
/* Setup for the export callback */
|
||||
import_data.keydata = keydata;
|
||||
import_data.keydata = NULL; /* try_import will create it */
|
||||
import_data.keymgmt = keymgmt;
|
||||
import_data.selection = OSSL_KEYMGMT_SELECT_ALL;
|
||||
|
||||
@@ -113,17 +122,17 @@ void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
|
||||
if (!evp_keymgmt_export(pk->keymgmt, pk->keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
&try_import, &import_data)) {
|
||||
/* If there was an error, bail out */
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
evp_keymgmt_freedata(keymgmt, import_data.keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the new export to the operation cache */
|
||||
if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, keydata)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
if (!evp_keymgmt_util_cache_keydata(pk, i, keymgmt, import_data.keydata)) {
|
||||
evp_keymgmt_freedata(keymgmt, import_data.keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return keydata;
|
||||
return import_data.keydata;
|
||||
}
|
||||
|
||||
void evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk)
|
||||
@@ -175,7 +184,7 @@ void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk)
|
||||
*
|
||||
* This services functions like EVP_PKEY_size, EVP_PKEY_bits, etc
|
||||
*/
|
||||
if (pk->keymgmt != NULL) {
|
||||
if (pk->keydata != NULL) {
|
||||
int bits = 0;
|
||||
int security_bits = 0;
|
||||
int size = 0;
|
||||
@@ -197,17 +206,15 @@ void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk)
|
||||
void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
|
||||
int selection, const OSSL_PARAM params[])
|
||||
{
|
||||
void *keydata = evp_keymgmt_newdata(keymgmt);
|
||||
void *keydata = NULL;
|
||||
|
||||
if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL
|
||||
|| !evp_keymgmt_import(keymgmt, keydata, selection, params)
|
||||
|| !EVP_PKEY_set_type_by_keymgmt(target, keymgmt)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
}
|
||||
if (keydata != NULL) {
|
||||
if (!evp_keymgmt_import(keymgmt, keydata, selection, params)
|
||||
|| !EVP_KEYMGMT_up_ref(keymgmt)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
evp_keymgmt_util_clear_operation_cache(target);
|
||||
target->keymgmt = keymgmt;
|
||||
target->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(target);
|
||||
}
|
||||
@@ -254,7 +261,17 @@ int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
|
||||
keydata2 = pk2->keydata;
|
||||
|
||||
if (keymgmt1 != keymgmt2) {
|
||||
void *tmp_keydata = NULL;
|
||||
/*
|
||||
* The condition for a successful cross export is that the
|
||||
* keydata to be exported is NULL (typed, but otherwise empty
|
||||
* EVP_PKEY), or that it was possible to export it with
|
||||
* evp_keymgmt_util_export_to_provider().
|
||||
*
|
||||
* We use |ok| to determine if it's ok to cross export one way,
|
||||
* but also to determine if we should attempt a cross export
|
||||
* the other way. There's no point doing it both ways.
|
||||
*/
|
||||
int ok = 1;
|
||||
|
||||
/* Complex case, where the keymgmt differ */
|
||||
if (keymgmt1 != NULL
|
||||
@@ -270,17 +287,35 @@ int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
|
||||
*/
|
||||
if (keymgmt2 != NULL
|
||||
&& keymgmt2->match != NULL) {
|
||||
tmp_keydata = evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
|
||||
if (tmp_keydata != NULL) {
|
||||
void *tmp_keydata = NULL;
|
||||
|
||||
ok = 1;
|
||||
if (keydata1 != NULL) {
|
||||
tmp_keydata =
|
||||
evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
|
||||
ok = (tmp_keydata != NULL);
|
||||
}
|
||||
if (ok) {
|
||||
keymgmt1 = keymgmt2;
|
||||
keydata1 = tmp_keydata;
|
||||
}
|
||||
}
|
||||
if (tmp_keydata == NULL
|
||||
/*
|
||||
* If we've successfully cross exported one way, there's no point
|
||||
* doing it the other way, hence the |!ok| check.
|
||||
*/
|
||||
if (!ok
|
||||
&& keymgmt1 != NULL
|
||||
&& keymgmt1->match != NULL) {
|
||||
tmp_keydata = evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
|
||||
if (tmp_keydata != NULL) {
|
||||
void *tmp_keydata = NULL;
|
||||
|
||||
ok = 1;
|
||||
if (keydata2 != NULL) {
|
||||
tmp_keydata =
|
||||
evp_keymgmt_util_export_to_provider(pk2, keymgmt1);
|
||||
ok = (tmp_keydata != NULL);
|
||||
}
|
||||
if (ok) {
|
||||
keymgmt2 = keymgmt1;
|
||||
keydata2 = tmp_keydata;
|
||||
}
|
||||
@@ -291,6 +326,13 @@ int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection)
|
||||
if (keymgmt1 != keymgmt2)
|
||||
return -2;
|
||||
|
||||
/* If both keydata are NULL, then they're the same key */
|
||||
if (keydata1 == NULL && keydata2 == NULL)
|
||||
return 1;
|
||||
/* If only one of the keydata is NULL, then they're different keys */
|
||||
if (keydata1 == NULL || keydata2 == NULL)
|
||||
return 0;
|
||||
/* If both keydata are non-NULL, we let the backend decide */
|
||||
return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection);
|
||||
}
|
||||
|
||||
@@ -301,23 +343,21 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
|
||||
void *to_keydata = to->keydata, *alloc_keydata = NULL;
|
||||
|
||||
/* An unassigned key can't be copied */
|
||||
if (from == NULL || from->keymgmt == NULL)
|
||||
if (from == NULL || from->keydata == NULL)
|
||||
return 0;
|
||||
|
||||
/* If |from| doesn't support copying, we fail */
|
||||
if (from->keymgmt->copy == NULL)
|
||||
return 0;
|
||||
|
||||
/* If |to| doesn't have a provider side "origin" yet, create one */
|
||||
if (to_keymgmt == NULL) {
|
||||
to_keydata = alloc_keydata = evp_keymgmt_newdata(from->keymgmt);
|
||||
if (to_keydata == NULL)
|
||||
if (to_keymgmt == from->keymgmt && to_keymgmt->copy != NULL) {
|
||||
/* Make sure there's somewhere to copy to */
|
||||
if (to_keydata == NULL
|
||||
&& (to_keydata = evp_keymgmt_newdata(to_keymgmt)) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
to_keymgmt = from->keymgmt;
|
||||
}
|
||||
}
|
||||
|
||||
if (to_keymgmt == from->keymgmt) {
|
||||
/* |to| and |from| have the same keymgmt, just copy and be done */
|
||||
/*
|
||||
* |to| and |from| have the same keymgmt, and the copy function is
|
||||
* implemented, so just copy and be done
|
||||
*/
|
||||
if (!evp_keymgmt_copy(to_keymgmt, to_keydata, from->keydata,
|
||||
selection))
|
||||
return 0;
|
||||
@@ -333,20 +373,42 @@ int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection)
|
||||
evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In this case to_keydata was previously unallocated, try_import()
|
||||
* may have created it for us.
|
||||
*/
|
||||
to_keydata = import_data.keydata;
|
||||
} else {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (to->keymgmt == NULL
|
||||
&& !EVP_KEYMGMT_up_ref(to_keymgmt)) {
|
||||
&& !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) {
|
||||
evp_keymgmt_freedata(to_keymgmt, alloc_keydata);
|
||||
return 0;
|
||||
}
|
||||
evp_keymgmt_util_clear_operation_cache(to);
|
||||
to->keymgmt = to_keymgmt;
|
||||
to->keydata = to_keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(to);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt,
|
||||
void *genctx, OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
void *keydata = NULL;
|
||||
|
||||
if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL
|
||||
|| !EVP_PKEY_set_type_by_keymgmt(target, keymgmt)) {
|
||||
evp_keymgmt_freedata(keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
}
|
||||
if (keydata != NULL) {
|
||||
target->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(target);
|
||||
}
|
||||
|
||||
return keydata;
|
||||
}
|
||||
+120
-3
@@ -38,7 +38,9 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
OSSL_PROVIDER *prov)
|
||||
{
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
int setparamfncnt = 0, getparamfncnt = 0, importfncnt = 0, exportfncnt = 0;
|
||||
int setparamfncnt = 0, getparamfncnt = 0;
|
||||
int setgenparamfncnt = 0, getgenparamfncnt = 0;
|
||||
int importfncnt = 0, exportfncnt = 0;
|
||||
|
||||
if ((keymgmt = keymgmt_new()) == NULL) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
@@ -52,6 +54,51 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
if (keymgmt->new == NULL)
|
||||
keymgmt->new = OSSL_get_OP_keymgmt_new(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_INIT:
|
||||
if (keymgmt->gen_init == NULL)
|
||||
keymgmt->gen_init = OSSL_get_OP_keymgmt_gen_init(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE:
|
||||
if (keymgmt->gen_set_template == NULL)
|
||||
keymgmt->gen_set_template =
|
||||
OSSL_get_OP_keymgmt_gen_set_template(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS:
|
||||
if (keymgmt->gen_set_params == NULL) {
|
||||
setgenparamfncnt++;
|
||||
keymgmt->gen_set_params =
|
||||
OSSL_get_OP_keymgmt_gen_set_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS:
|
||||
if (keymgmt->gen_settable_params == NULL) {
|
||||
setgenparamfncnt++;
|
||||
keymgmt->gen_settable_params =
|
||||
OSSL_get_OP_keymgmt_gen_settable_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_GET_PARAMS:
|
||||
if (keymgmt->gen_get_params == NULL) {
|
||||
getgenparamfncnt++;
|
||||
keymgmt->gen_get_params =
|
||||
OSSL_get_OP_keymgmt_gen_get_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_GETTABLE_PARAMS:
|
||||
if (keymgmt->gen_gettable_params == NULL) {
|
||||
getgenparamfncnt++;
|
||||
keymgmt->gen_gettable_params =
|
||||
OSSL_get_OP_keymgmt_gen_gettable_params(fns);
|
||||
}
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN:
|
||||
if (keymgmt->gen == NULL)
|
||||
keymgmt->gen = OSSL_get_OP_keymgmt_gen(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_GEN_CLEANUP:
|
||||
if (keymgmt->gen_cleanup == NULL)
|
||||
keymgmt->gen_cleanup = OSSL_get_OP_keymgmt_gen_cleanup(fns);
|
||||
break;
|
||||
case OSSL_FUNC_KEYMGMT_FREE:
|
||||
if (keymgmt->free == NULL)
|
||||
keymgmt->free = OSSL_get_OP_keymgmt_free(fns);
|
||||
@@ -134,12 +181,17 @@ static void *keymgmt_from_dispatch(int name_id,
|
||||
* export if you can't import or export.
|
||||
*/
|
||||
if (keymgmt->free == NULL
|
||||
|| keymgmt->new == NULL
|
||||
|| (keymgmt->new == NULL && keymgmt->gen == NULL)
|
||||
|| keymgmt->has == NULL
|
||||
|| (getparamfncnt != 0 && getparamfncnt != 2)
|
||||
|| (setparamfncnt != 0 && setparamfncnt != 2)
|
||||
|| (setgenparamfncnt != 0 && setgenparamfncnt != 2)
|
||||
|| (getgenparamfncnt != 0 && getgenparamfncnt != 2)
|
||||
|| (importfncnt != 0 && importfncnt != 2)
|
||||
|| (exportfncnt != 0 && exportfncnt != 2)) {
|
||||
|| (exportfncnt != 0 && exportfncnt != 2)
|
||||
|| (keymgmt->gen != NULL
|
||||
&& (keymgmt->gen_init == NULL
|
||||
|| keymgmt->gen_cleanup == NULL))) {
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
EVPerr(0, EVP_R_INVALID_PROVIDER_FUNCTIONS);
|
||||
return NULL;
|
||||
@@ -249,6 +301,71 @@ void evp_keymgmt_freedata(const EVP_KEYMGMT *keymgmt, void *keydata)
|
||||
keymgmt->free(keydata);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_gen_init(const EVP_KEYMGMT *keymgmt, int selection)
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
if (keymgmt->gen_init == NULL)
|
||||
return NULL;
|
||||
return keymgmt->gen_init(provctx, selection);
|
||||
}
|
||||
|
||||
int evp_keymgmt_gen_set_template(const EVP_KEYMGMT *keymgmt, void *genctx,
|
||||
void *template)
|
||||
{
|
||||
if (keymgmt->gen_set_template == NULL)
|
||||
return 0;
|
||||
return keymgmt->gen_set_template(genctx, template);
|
||||
}
|
||||
|
||||
int evp_keymgmt_gen_set_params(const EVP_KEYMGMT *keymgmt, void *genctx,
|
||||
const OSSL_PARAM params[])
|
||||
{
|
||||
if (keymgmt->gen_set_params == NULL)
|
||||
return 0;
|
||||
return keymgmt->gen_set_params(genctx, params);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_gen_settable_params(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
if (keymgmt->gen_settable_params == NULL)
|
||||
return NULL;
|
||||
return keymgmt->gen_settable_params(provctx);
|
||||
}
|
||||
|
||||
int evp_keymgmt_gen_get_params(const EVP_KEYMGMT *keymgmt, void *genctx,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
if (keymgmt->gen_get_params == NULL)
|
||||
return 0;
|
||||
return keymgmt->gen_get_params(genctx, params);
|
||||
}
|
||||
|
||||
const OSSL_PARAM *evp_keymgmt_gen_gettable_params(const EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
void *provctx = ossl_provider_ctx(EVP_KEYMGMT_provider(keymgmt));
|
||||
|
||||
if (keymgmt->gen_gettable_params == NULL)
|
||||
return NULL;
|
||||
return keymgmt->gen_gettable_params(provctx);
|
||||
}
|
||||
|
||||
void *evp_keymgmt_gen(const EVP_KEYMGMT *keymgmt, void *genctx,
|
||||
OSSL_CALLBACK *cb, void *cbarg)
|
||||
{
|
||||
if (keymgmt->gen == NULL)
|
||||
return NULL;
|
||||
return keymgmt->gen(genctx, cb, cbarg);
|
||||
}
|
||||
|
||||
void evp_keymgmt_gen_cleanup(const EVP_KEYMGMT *keymgmt, void *genctx)
|
||||
{
|
||||
if (keymgmt->gen != NULL)
|
||||
keymgmt->gen_cleanup(genctx);
|
||||
}
|
||||
|
||||
int evp_keymgmt_get_params(const EVP_KEYMGMT *keymgmt, void *keydata,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
|
||||
+101
-17
@@ -24,10 +24,22 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get the "NULL" md then the name comes back as "UNDEF". We want to use
|
||||
* NULL for this.
|
||||
*/
|
||||
static const char *canon_mdname(const char *mdname)
|
||||
{
|
||||
if (mdname != NULL && strcmp(mdname, "UNDEF") == 0)
|
||||
return NULL;
|
||||
|
||||
return mdname;
|
||||
}
|
||||
|
||||
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
const EVP_MD *type, const char *mdname,
|
||||
const char *props, ENGINE *e, EVP_PKEY *pkey,
|
||||
int ver)
|
||||
OPENSSL_CTX *libctx, int ver)
|
||||
{
|
||||
EVP_PKEY_CTX *locpctx = NULL;
|
||||
EVP_SIGNATURE *signature = NULL;
|
||||
@@ -47,8 +59,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
ctx->provctx = NULL;
|
||||
}
|
||||
|
||||
if (ctx->pctx == NULL)
|
||||
ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
|
||||
if (ctx->pctx == NULL) {
|
||||
if (libctx != NULL)
|
||||
ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
|
||||
else
|
||||
ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
|
||||
}
|
||||
if (ctx->pctx == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -61,7 +77,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
*/
|
||||
ERR_set_mark();
|
||||
|
||||
if (locpctx->keytype == NULL)
|
||||
if (locpctx->engine != NULL || locpctx->keytype == NULL)
|
||||
goto legacy;
|
||||
|
||||
/*
|
||||
@@ -134,12 +150,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
if (type != NULL) {
|
||||
ctx->reqdigest = type;
|
||||
if (mdname == NULL)
|
||||
mdname = EVP_MD_name(type);
|
||||
mdname = canon_mdname(EVP_MD_name(type));
|
||||
} else {
|
||||
if (mdname == NULL
|
||||
&& EVP_PKEY_get_default_digest_name(locpctx->pkey, locmdname,
|
||||
sizeof(locmdname)))
|
||||
mdname = locmdname;
|
||||
mdname = canon_mdname(locmdname);
|
||||
|
||||
if (mdname != NULL) {
|
||||
/*
|
||||
@@ -184,6 +200,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
*/
|
||||
ERR_pop_to_mark();
|
||||
|
||||
if (type == NULL && mdname != NULL)
|
||||
type = evp_get_digestbyname_ex(locpctx->libctx, mdname);
|
||||
|
||||
if (ctx->pctx->pmeth == NULL) {
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return 0;
|
||||
@@ -238,35 +257,38 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
* This indicates the current algorithm requires
|
||||
* special treatment before hashing the tbs-message.
|
||||
*/
|
||||
ctx->pctx->flag_call_digest_custom = 0;
|
||||
if (ctx->pctx->pmeth->digest_custom != NULL)
|
||||
return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
|
||||
ctx->pctx->flag_call_digest_custom = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
const char *mdname, const char *props, EVP_PKEY *pkey)
|
||||
const char *mdname, const char *props, EVP_PKEY *pkey,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 0);
|
||||
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx,
|
||||
0);
|
||||
}
|
||||
|
||||
int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
|
||||
{
|
||||
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 0);
|
||||
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 0);
|
||||
}
|
||||
|
||||
int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
const char *mdname, const char *props,
|
||||
EVP_PKEY *pkey)
|
||||
EVP_PKEY *pkey, OPENSSL_CTX *libctx)
|
||||
{
|
||||
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, 1);
|
||||
return do_sigver_init(ctx, pctx, NULL, mdname, props, NULL, pkey, libctx, 1);
|
||||
}
|
||||
|
||||
int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
||||
const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
|
||||
{
|
||||
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, 1);
|
||||
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1);
|
||||
}
|
||||
#endif /* FIPS_MDOE */
|
||||
|
||||
@@ -280,10 +302,21 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|
||||
|| pctx->op.sig.signature == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (pctx->op.sig.signature->digest_sign_update == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pctx->op.sig.signature->digest_sign_update(pctx->op.sig.sigprovctx,
|
||||
data, dsize);
|
||||
|
||||
legacy:
|
||||
/* do_sigver_init() checked that |digest_custom| is non-NULL */
|
||||
if (pctx->flag_call_digest_custom
|
||||
&& !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
|
||||
return 0;
|
||||
pctx->flag_call_digest_custom = 0;
|
||||
|
||||
return EVP_DigestUpdate(ctx, data, dsize);
|
||||
}
|
||||
|
||||
@@ -297,10 +330,21 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|
||||
|| pctx->op.sig.signature == NULL)
|
||||
goto legacy;
|
||||
|
||||
if (pctx->op.sig.signature->digest_verify_update == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return pctx->op.sig.signature->digest_verify_update(pctx->op.sig.sigprovctx,
|
||||
data, dsize);
|
||||
|
||||
legacy:
|
||||
/* do_sigver_init() checked that |digest_custom| is non-NULL */
|
||||
if (pctx->flag_call_digest_custom
|
||||
&& !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
|
||||
return 0;
|
||||
pctx->flag_call_digest_custom = 0;
|
||||
|
||||
return EVP_DigestUpdate(ctx, data, dsize);
|
||||
}
|
||||
|
||||
@@ -326,6 +370,12 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do_sigver_init() checked that |digest_custom| is non-NULL */
|
||||
if (pctx->flag_call_digest_custom
|
||||
&& !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
|
||||
return 0;
|
||||
pctx->flag_call_digest_custom = 0;
|
||||
|
||||
if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
|
||||
if (sigret == NULL)
|
||||
return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
|
||||
@@ -391,8 +441,22 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|
||||
int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
|
||||
return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
|
||||
EVP_PKEY_CTX *pctx = ctx->pctx;
|
||||
|
||||
if (pctx != NULL
|
||||
&& pctx->operation == EVP_PKEY_OP_SIGNCTX
|
||||
&& pctx->op.sig.sigprovctx != NULL
|
||||
&& pctx->op.sig.signature != NULL) {
|
||||
if (pctx->op.sig.signature->digest_sign != NULL)
|
||||
return pctx->op.sig.signature->digest_sign(pctx->op.sig.sigprovctx,
|
||||
sigret, siglen, SIZE_MAX,
|
||||
tbs, tbslen);
|
||||
} else {
|
||||
/* legacy */
|
||||
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
|
||||
return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen, tbs, tbslen);
|
||||
}
|
||||
|
||||
if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
|
||||
return 0;
|
||||
return EVP_DigestSignFinal(ctx, sigret, siglen);
|
||||
@@ -422,6 +486,12 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* do_sigver_init() checked that |digest_custom| is non-NULL */
|
||||
if (pctx->flag_call_digest_custom
|
||||
&& !ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx))
|
||||
return 0;
|
||||
pctx->flag_call_digest_custom = 0;
|
||||
|
||||
if (pctx->pmeth->verifyctx != NULL)
|
||||
vctx = 1;
|
||||
else
|
||||
@@ -454,8 +524,22 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
|
||||
size_t siglen, const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
|
||||
return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
|
||||
EVP_PKEY_CTX *pctx = ctx->pctx;
|
||||
|
||||
if (pctx != NULL
|
||||
&& pctx->operation == EVP_PKEY_OP_VERIFYCTX
|
||||
&& pctx->op.sig.sigprovctx != NULL
|
||||
&& pctx->op.sig.signature != NULL) {
|
||||
if (pctx->op.sig.signature->digest_verify != NULL)
|
||||
return pctx->op.sig.signature->digest_verify(pctx->op.sig.sigprovctx,
|
||||
sigret, siglen,
|
||||
tbs, tbslen);
|
||||
} else {
|
||||
/* legacy */
|
||||
if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
|
||||
return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
|
||||
}
|
||||
|
||||
if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
|
||||
return -1;
|
||||
return EVP_DigestVerifyFinal(ctx, sigret, siglen);
|
||||
|
||||
+666
-203
@@ -24,6 +24,7 @@
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/params.h>
|
||||
@@ -32,13 +33,24 @@
|
||||
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "internal/evp.h"
|
||||
#include "internal/provider.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
#include "crypto/ec.h"
|
||||
|
||||
/* TODO remove this when the EVP_PKEY_is_a() #legacy support hack is removed */
|
||||
#include "e_os.h" /* strcasecmp on Windows */
|
||||
|
||||
static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
|
||||
int len, EVP_KEYMGMT *keymgmt);
|
||||
static void evp_pkey_free_it(EVP_PKEY *key);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
|
||||
/* The type of parameters selected in key parameter functions */
|
||||
# define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
|
||||
|
||||
int EVP_PKEY_bits(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey != NULL) {
|
||||
@@ -84,6 +96,16 @@ int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_ex_data(EVP_PKEY *key, int idx, void *arg)
|
||||
{
|
||||
return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
|
||||
}
|
||||
|
||||
void *EVP_PKEY_get_ex_data(const EVP_PKEY *key, int idx)
|
||||
{
|
||||
return CRYPTO_get_ex_data(&key->ex_data, idx);
|
||||
}
|
||||
|
||||
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
{
|
||||
/*
|
||||
@@ -92,16 +114,35 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Only check that type match this early when both keys are legacy.
|
||||
* If either of them is provided, we let evp_keymgmt_util_copy()
|
||||
* do this check, after having exported either of them that isn't
|
||||
* provided.
|
||||
* If |to| is a legacy key and |from| isn't, we must downgrade |from|.
|
||||
* If that fails, this function fails.
|
||||
*/
|
||||
if (to->keymgmt == NULL && from->keymgmt == NULL) {
|
||||
if (to->type == EVP_PKEY_NONE) {
|
||||
if (to->type != EVP_PKEY_NONE && from->keymgmt != NULL)
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)from))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Make sure |to| is typed. Content is less important at this early
|
||||
* stage.
|
||||
*
|
||||
* 1. If |to| is untyped, assign |from|'s key type to it.
|
||||
* 2. If |to| contains a legacy key, compare its |type| to |from|'s.
|
||||
* (|from| was already downgraded above)
|
||||
*
|
||||
* If |to| is a provided key, there's nothing more to do here, functions
|
||||
* like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called
|
||||
* further down help us find out if they are the same or not.
|
||||
*/
|
||||
if (to->type == EVP_PKEY_NONE && to->keymgmt == NULL) {
|
||||
if (from->type != EVP_PKEY_NONE) {
|
||||
if (EVP_PKEY_set_type(to, from->type) == 0)
|
||||
return 0;
|
||||
} else if (to->type != from->type) {
|
||||
} else {
|
||||
if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0)
|
||||
return 0;
|
||||
}
|
||||
} else if (to->type != EVP_PKEY_NONE) {
|
||||
if (to->type != from->type) {
|
||||
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
goto err;
|
||||
}
|
||||
@@ -119,34 +160,9 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If |from| is provided, we upgrade |to| to be provided as well.
|
||||
* This drops the legacy key from |to|.
|
||||
* evp_pkey_upgrade_to_provider() checks if |to| is already provided,
|
||||
* we don't need to do that here.
|
||||
*
|
||||
* TODO(3.0) We should investigate if that's too aggressive and make
|
||||
* this scenario unsupported instead.
|
||||
*/
|
||||
if (from->keymgmt != NULL) {
|
||||
EVP_KEYMGMT *tmp_keymgmt = from->keymgmt;
|
||||
|
||||
/*
|
||||
* The returned pointer is known to be cached, so we don't have to
|
||||
* save it. However, if it's NULL, something went wrong and we can't
|
||||
* copy.
|
||||
*/
|
||||
if (evp_pkey_upgrade_to_provider(to, NULL,
|
||||
&tmp_keymgmt, NULL) == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* For purely provided keys, we just call the keymgmt utility */
|
||||
if (to->keymgmt != NULL && from->keymgmt != NULL)
|
||||
return evp_keymgmt_util_copy(to, (EVP_PKEY *)from,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
return evp_keymgmt_util_copy(to, (EVP_PKEY *)from, SELECT_PARAMETERS);
|
||||
|
||||
/*
|
||||
* If |to| is provided, we know that |from| is legacy at this point.
|
||||
@@ -159,12 +175,16 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
|
||||
evp_pkey_export_to_provider((EVP_PKEY *)from, NULL, &to_keymgmt,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* If we get a NULL, it could be an internal error, or it could be
|
||||
* that there's a key mismatch. We're pretending the latter...
|
||||
*/
|
||||
if (from_keydata == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES);
|
||||
return 0;
|
||||
}
|
||||
return evp_keymgmt_copy(to->keymgmt, to->keydata, from_keydata,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
SELECT_PARAMETERS);
|
||||
}
|
||||
|
||||
/* Both keys are legacy */
|
||||
@@ -178,8 +198,7 @@ int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey != NULL) {
|
||||
if (pkey->keymgmt != NULL)
|
||||
return !evp_keymgmt_util_has((EVP_PKEY *)pkey,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
return !evp_keymgmt_util_has((EVP_PKEY *)pkey, SELECT_PARAMETERS);
|
||||
else if (pkey->ameth != NULL && pkey->ameth->param_missing != NULL)
|
||||
return pkey->ameth->param_missing(pkey);
|
||||
}
|
||||
@@ -206,20 +225,25 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
|
||||
return evp_keymgmt_util_match((EVP_PKEY *)a, (EVP_PKEY *)b, selection);
|
||||
|
||||
/*
|
||||
* Here, we know that we have a mixture of legacy and provided keys.
|
||||
* Try cross export and compare the resulting key data.
|
||||
* At this point, one of them is provided, the other not. This allows
|
||||
* us to compare types using legacy NIDs.
|
||||
*/
|
||||
if ((a->type != EVP_PKEY_NONE
|
||||
&& !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type)))
|
||||
|| (b->type != EVP_PKEY_NONE
|
||||
&& !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type))))
|
||||
return -1; /* not the same key type */
|
||||
|
||||
/*
|
||||
* We've determined that they both are the same keytype, so the next
|
||||
* step is to do a bit of cross export to ensure we have keydata for
|
||||
* both keys in the same keymgmt.
|
||||
*/
|
||||
keymgmt1 = a->keymgmt;
|
||||
keydata1 = a->keydata;
|
||||
keymgmt2 = b->keymgmt;
|
||||
keydata2 = b->keydata;
|
||||
|
||||
if ((keymgmt1 == NULL
|
||||
&& !EVP_KEYMGMT_is_a(keymgmt2, OBJ_nid2sn(a->type)))
|
||||
|| (keymgmt2 == NULL
|
||||
&& !EVP_KEYMGMT_is_a(keymgmt1, OBJ_nid2sn(b->type))))
|
||||
return -1; /* not the same key type */
|
||||
|
||||
if (keymgmt2 != NULL && keymgmt2->match != NULL) {
|
||||
tmp_keydata =
|
||||
evp_pkey_export_to_provider((EVP_PKEY *)a, NULL, &keymgmt2, NULL);
|
||||
@@ -252,7 +276,7 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
*/
|
||||
|
||||
if (a->keymgmt != NULL || b->keymgmt != NULL)
|
||||
return evp_pkey_cmp_any(a, b, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
return evp_pkey_cmp_any(a, b, SELECT_PARAMETERS);
|
||||
|
||||
/* All legacy keys */
|
||||
if (a->type != b->type)
|
||||
@@ -270,9 +294,8 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
*/
|
||||
|
||||
if (a->keymgmt != NULL || b->keymgmt != NULL)
|
||||
return evp_pkey_cmp_any(a, b,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
|
||||
| OSSL_KEYMGMT_SELECT_PUBLIC_KEY);
|
||||
return evp_pkey_cmp_any(a, b, (SELECT_PARAMETERS
|
||||
| OSSL_KEYMGMT_SELECT_PUBLIC_KEY));
|
||||
|
||||
/* All legacy keys */
|
||||
if (a->type != b->type)
|
||||
@@ -294,57 +317,6 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
|
||||
* is NULL just return 1 or 0 if the algorithm exists.
|
||||
*/
|
||||
|
||||
static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
|
||||
int len)
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ENGINE **eptr = (e == NULL) ? &e : NULL;
|
||||
|
||||
if (pkey) {
|
||||
if (pkey->pkey.ptr)
|
||||
evp_pkey_free_it(pkey);
|
||||
/*
|
||||
* If key type matches and a method exists then this lookup has
|
||||
* succeeded once so just indicate success.
|
||||
*/
|
||||
if ((type == pkey->save_type) && pkey->ameth)
|
||||
return 1;
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
/* If we have ENGINEs release them */
|
||||
ENGINE_finish(pkey->engine);
|
||||
pkey->engine = NULL;
|
||||
ENGINE_finish(pkey->pmeth_engine);
|
||||
pkey->pmeth_engine = NULL;
|
||||
# endif
|
||||
}
|
||||
if (str)
|
||||
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
|
||||
else
|
||||
ameth = EVP_PKEY_asn1_find(eptr, type);
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
if (pkey == NULL && eptr != NULL)
|
||||
ENGINE_finish(e);
|
||||
# endif
|
||||
if (ameth == NULL) {
|
||||
EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
if (pkey) {
|
||||
pkey->ameth = ameth;
|
||||
pkey->engine = e;
|
||||
|
||||
pkey->type = pkey->ameth->pkey_id;
|
||||
pkey->save_type = type;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
|
||||
const unsigned char *priv,
|
||||
size_t len)
|
||||
@@ -352,7 +324,7 @@ EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
|
||||
if (ret == NULL
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1)) {
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1, NULL)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
@@ -382,7 +354,7 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
|
||||
EVP_PKEY *ret = EVP_PKEY_new();
|
||||
|
||||
if (ret == NULL
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1)) {
|
||||
|| !pkey_set_type(ret, e, type, NULL, -1, NULL)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
@@ -408,6 +380,7 @@ EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
|
||||
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
size_t *len)
|
||||
{
|
||||
/* TODO(3.0) Do we need to do anything about provider side keys? */
|
||||
if (pkey->ameth->get_priv_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
@@ -425,6 +398,7 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
|
||||
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
|
||||
size_t *len)
|
||||
{
|
||||
/* TODO(3.0) Do we need to do anything about provider side keys? */
|
||||
if (pkey->ameth->get_pub_key == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
@@ -457,8 +431,8 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
size_t paramsn = 0;
|
||||
|
||||
if (ret == NULL
|
||||
|| cmctx == NULL
|
||||
|| !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) {
|
||||
|| cmctx == NULL
|
||||
|| !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1, NULL)) {
|
||||
/* EVPerr already called */
|
||||
goto err;
|
||||
}
|
||||
@@ -499,12 +473,12 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
|
||||
|
||||
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
|
||||
{
|
||||
return pkey_set_type(pkey, NULL, type, NULL, -1);
|
||||
return pkey_set_type(pkey, NULL, type, NULL, -1, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
|
||||
{
|
||||
return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
|
||||
return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
|
||||
@@ -573,6 +547,10 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
|
||||
|
||||
void *EVP_PKEY_get0(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
return pkey->pkey.ptr;
|
||||
}
|
||||
|
||||
@@ -628,6 +606,10 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
|
||||
|
||||
RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
|
||||
return NULL;
|
||||
@@ -655,6 +637,10 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
|
||||
|
||||
DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
if (pkey->type != EVP_PKEY_DSA) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
|
||||
return NULL;
|
||||
@@ -683,6 +669,10 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
|
||||
|
||||
EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
|
||||
return NULL;
|
||||
@@ -713,6 +703,10 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
|
||||
|
||||
DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (!evp_pkey_downgrade((EVP_PKEY *)pkey)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY);
|
||||
return NULL;
|
||||
}
|
||||
if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
|
||||
EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
|
||||
return NULL;
|
||||
@@ -755,6 +749,119 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey)
|
||||
return EVP_PKEY_type(pkey->type);
|
||||
}
|
||||
|
||||
int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
if (pkey->keymgmt == NULL) {
|
||||
/*
|
||||
* These hard coded cases are pure hackery to get around the fact
|
||||
* that names in crypto/objects/objects.txt are a mess. There is
|
||||
* no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's
|
||||
* fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1,
|
||||
* the NID of which is used for EVP_PKEY_RSA. Strangely enough,
|
||||
* "DSA" is accurate... but still, better be safe and hard-code
|
||||
* names that we know.
|
||||
* TODO Clean this away along with all other #legacy support.
|
||||
*/
|
||||
int type;
|
||||
|
||||
if (strcasecmp(name, "RSA") == 0)
|
||||
type = EVP_PKEY_RSA;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
else if (strcasecmp(name, "EC") == 0)
|
||||
type = EVP_PKEY_EC;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
else if (strcasecmp(name, "DSA") == 0)
|
||||
type = EVP_PKEY_DSA;
|
||||
#endif
|
||||
else
|
||||
type = EVP_PKEY_type(OBJ_sn2nid(name));
|
||||
return EVP_PKEY_type(pkey->type) == type;
|
||||
}
|
||||
#endif
|
||||
return EVP_KEYMGMT_is_a(pkey->keymgmt, name);
|
||||
}
|
||||
|
||||
int EVP_PKEY_can_sign(const EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey->keymgmt == NULL) {
|
||||
switch (EVP_PKEY_base_id(pkey)) {
|
||||
case EVP_PKEY_RSA:
|
||||
return 1;
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
case EVP_PKEY_DSA:
|
||||
return 1;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
case EVP_PKEY_ED25519:
|
||||
case EVP_PKEY_ED448:
|
||||
return 1;
|
||||
case EVP_PKEY_EC: /* Including SM2 */
|
||||
return EC_KEY_can_sign(pkey->pkey.ec);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
const OSSL_PROVIDER *prov = EVP_KEYMGMT_provider(pkey->keymgmt);
|
||||
OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
|
||||
const char *supported_sig =
|
||||
pkey->keymgmt->query_operation_name != NULL
|
||||
? pkey->keymgmt->query_operation_name(OSSL_OP_SIGNATURE)
|
||||
: evp_first_name(prov, pkey->keymgmt->name_id);
|
||||
EVP_SIGNATURE *signature = NULL;
|
||||
|
||||
signature = EVP_SIGNATURE_fetch(libctx, supported_sig, NULL);
|
||||
if (signature != NULL) {
|
||||
EVP_SIGNATURE_free(signature);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
/*
|
||||
* TODO rewrite when we have proper data extraction functions
|
||||
* Note: an octet pointer would be desirable!
|
||||
*/
|
||||
static OSSL_CALLBACK get_ec_curve_name_cb;
|
||||
static int get_ec_curve_name_cb(const OSSL_PARAM params[], void *arg)
|
||||
{
|
||||
const OSSL_PARAM *p = NULL;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL)
|
||||
return OSSL_PARAM_get_utf8_string(p, arg, 0);
|
||||
|
||||
/* If there is no curve name, this is not an EC key */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int evp_pkey_get_EC_KEY_curve_nid(const EVP_PKEY *pkey)
|
||||
{
|
||||
int ret = NID_undef;
|
||||
|
||||
if (pkey->keymgmt == NULL) {
|
||||
if (EVP_PKEY_base_id(pkey) == EVP_PKEY_EC) {
|
||||
EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
|
||||
|
||||
ret = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
|
||||
}
|
||||
} else if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "SM2")) {
|
||||
char *curve_name = NULL;
|
||||
|
||||
ret = evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
|
||||
OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
|
||||
get_ec_curve_name_cb, &curve_name);
|
||||
if (ret)
|
||||
ret = ec_curve_name2nid(curve_name);
|
||||
OPENSSL_free(curve_name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int print_reset_indent(BIO **out, int pop_f_prefix, long saved_indent)
|
||||
{
|
||||
@@ -993,10 +1100,192 @@ EVP_PKEY *EVP_PKEY_new(void)
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
if (ret->lock == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
#ifndef FIPS_MODE
|
||||
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
|
||||
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
|
||||
err:
|
||||
CRYPTO_THREAD_lock_free(ret->lock);
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a public key management method.
|
||||
*
|
||||
* For legacy keys, either |type| or |str| is expected to have the type
|
||||
* information. In this case, the setup consists of finding an ASN1 method
|
||||
* and potentially an ENGINE, and setting those fields in |pkey|.
|
||||
*
|
||||
* For provider side keys, |keymgmt| is expected to be non-NULL. In this
|
||||
* case, the setup consists of setting the |keymgmt| field in |pkey|.
|
||||
*
|
||||
* If pkey is NULL just return 1 or 0 if the key management method exists.
|
||||
*/
|
||||
|
||||
static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
|
||||
int len, EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
|
||||
ENGINE **eptr = (e == NULL) ? &e : NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The setups can't set both legacy and provider side methods.
|
||||
* It is forbidden
|
||||
*/
|
||||
if (!ossl_assert(type == EVP_PKEY_NONE || keymgmt == NULL)
|
||||
|| !ossl_assert(e == NULL || keymgmt == NULL)) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkey != NULL) {
|
||||
int free_it = 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
free_it = free_it || pkey->pkey.ptr != NULL;
|
||||
#endif
|
||||
free_it = free_it || pkey->keydata != NULL;
|
||||
if (free_it)
|
||||
evp_pkey_free_it(pkey);
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* If key type matches and a method exists then this lookup has
|
||||
* succeeded once so just indicate success.
|
||||
*/
|
||||
if (pkey->type != EVP_PKEY_NONE
|
||||
&& type == pkey->save_type
|
||||
&& pkey->ameth != NULL)
|
||||
return 1;
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
/* If we have ENGINEs release them */
|
||||
ENGINE_finish(pkey->engine);
|
||||
pkey->engine = NULL;
|
||||
ENGINE_finish(pkey->pmeth_engine);
|
||||
pkey->pmeth_engine = NULL;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#ifndef FIPS_MODE
|
||||
if (str != NULL)
|
||||
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
|
||||
else if (type != EVP_PKEY_NONE)
|
||||
ameth = EVP_PKEY_asn1_find(eptr, type);
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
if (pkey == NULL && eptr != NULL)
|
||||
ENGINE_finish(e);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
{
|
||||
int check = 1;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
check = check && ameth == NULL;
|
||||
#endif
|
||||
check = check && keymgmt == NULL;
|
||||
if (check) {
|
||||
EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (pkey != NULL) {
|
||||
if (keymgmt != NULL && !EVP_KEYMGMT_up_ref(keymgmt)) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkey->keymgmt = keymgmt;
|
||||
|
||||
pkey->save_type = type;
|
||||
pkey->type = type;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* If the internal "origin" key is provider side, don't save |ameth|.
|
||||
* The main reason is that |ameth| is one factor to detect that the
|
||||
* internal "origin" key is a legacy one.
|
||||
*/
|
||||
if (keymgmt == NULL)
|
||||
pkey->ameth = ameth;
|
||||
pkey->engine = e;
|
||||
|
||||
/*
|
||||
* The EVP_PKEY_ASN1_METHOD |pkey_id| serves different purposes,
|
||||
* depending on if we're setting this key to contain a legacy or
|
||||
* a provider side "origin" key. For a legacy key, we assign it
|
||||
* to the |type| field, but for a provider side key, we assign it
|
||||
* to the |save_type| field, because |type| is supposed to be set
|
||||
* to EVP_PKEY_NONE in that case.
|
||||
*/
|
||||
if (keymgmt != NULL)
|
||||
pkey->save_type = ameth->pkey_id;
|
||||
else if (pkey->ameth != NULL)
|
||||
pkey->type = ameth->pkey_id;
|
||||
#endif
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
static void find_ameth(const char *name, void *data)
|
||||
{
|
||||
const char **str = data;
|
||||
|
||||
/*
|
||||
* The error messages from pkey_set_type() are uninteresting here,
|
||||
* and misleading.
|
||||
*/
|
||||
ERR_set_mark();
|
||||
|
||||
if (pkey_set_type(NULL, NULL, EVP_PKEY_NONE, name, strlen(name),
|
||||
NULL)) {
|
||||
if (str[0] == NULL)
|
||||
str[0] = name;
|
||||
else if (str[1] == NULL)
|
||||
str[1] = name;
|
||||
}
|
||||
|
||||
ERR_pop_to_mark();
|
||||
}
|
||||
#endif
|
||||
|
||||
int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
|
||||
{
|
||||
#ifndef FIPS_MODE
|
||||
# define EVP_PKEY_TYPE_STR str[0]
|
||||
# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
|
||||
/*
|
||||
* Find at most two strings that have an associated EVP_PKEY_ASN1_METHOD
|
||||
* Ideally, only one should be found. If two (or more) are found, the
|
||||
* match is ambiguous. This should never happen, but...
|
||||
*/
|
||||
const char *str[2] = { NULL, NULL };
|
||||
|
||||
EVP_KEYMGMT_names_do_all(keymgmt, find_ameth, &str);
|
||||
if (str[1] != NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
# define EVP_PKEY_TYPE_STR NULL
|
||||
# define EVP_PKEY_TYPE_STRLEN -1
|
||||
#endif
|
||||
return pkey_set_type(pkey, NULL, EVP_PKEY_NONE,
|
||||
EVP_PKEY_TYPE_STR, EVP_PKEY_TYPE_STRLEN,
|
||||
keymgmt);
|
||||
|
||||
#undef EVP_PKEY_TYPE_STR
|
||||
#undef EVP_PKEY_TYPE_STRLEN
|
||||
}
|
||||
|
||||
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
|
||||
@@ -1012,13 +1301,12 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
static void evp_pkey_free_legacy(EVP_PKEY *x)
|
||||
void evp_pkey_free_legacy(EVP_PKEY *x)
|
||||
{
|
||||
if (x->ameth != NULL) {
|
||||
if (x->ameth->pkey_free != NULL)
|
||||
x->ameth->pkey_free(x);
|
||||
x->pkey.ptr = NULL;
|
||||
x->ameth = NULL;
|
||||
}
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_finish(x->engine);
|
||||
@@ -1026,7 +1314,7 @@ static void evp_pkey_free_legacy(EVP_PKEY *x)
|
||||
ENGINE_finish(x->pmeth_engine);
|
||||
x->pmeth_engine = NULL;
|
||||
# endif
|
||||
x->type = x->save_type = EVP_PKEY_NONE;
|
||||
x->type = EVP_PKEY_NONE;
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
@@ -1060,6 +1348,9 @@ void EVP_PKEY_free(EVP_PKEY *x)
|
||||
return;
|
||||
REF_ASSERT_ISNT(i < 0);
|
||||
evp_pkey_free_it(x);
|
||||
#ifndef FIPS_MODE
|
||||
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
|
||||
#endif
|
||||
CRYPTO_THREAD_lock_free(x->lock);
|
||||
#ifndef FIPS_MODE
|
||||
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
|
||||
@@ -1069,13 +1360,16 @@ void EVP_PKEY_free(EVP_PKEY *x)
|
||||
|
||||
int EVP_PKEY_size(const EVP_PKEY *pkey)
|
||||
{
|
||||
int size = 0;
|
||||
|
||||
if (pkey != NULL) {
|
||||
if (pkey->ameth == NULL)
|
||||
return pkey->cache.size;
|
||||
else if (pkey->ameth->pkey_size != NULL)
|
||||
return pkey->ameth->pkey_size(pkey);
|
||||
size = pkey->cache.size;
|
||||
#ifndef FIPS_MODE
|
||||
if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
|
||||
size = pkey->ameth->pkey_size(pkey);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
@@ -1085,10 +1379,20 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT *allocated_keymgmt = NULL;
|
||||
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
||||
void *keydata = NULL;
|
||||
int check;
|
||||
|
||||
if (pk == NULL)
|
||||
return NULL;
|
||||
|
||||
/* No key data => nothing to export */
|
||||
check = 1;
|
||||
#ifndef FIPS_MODE
|
||||
check = check && pk->pkey.ptr == NULL;
|
||||
#endif
|
||||
check = check && pk->keydata == NULL;
|
||||
if (check)
|
||||
return NULL;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (pk->pkey.ptr != NULL) {
|
||||
/*
|
||||
@@ -1105,13 +1409,15 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
*keymgmt = NULL;
|
||||
}
|
||||
|
||||
/* If no keymgmt was given or found, get a default keymgmt */
|
||||
/*
|
||||
* If no keymgmt was given or found, get a default keymgmt. We do so by
|
||||
* letting EVP_PKEY_CTX_new_from_pkey() do it for us, then we steal it.
|
||||
*/
|
||||
if (tmp_keymgmt == NULL) {
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
|
||||
|
||||
if (ctx != NULL && ctx->keytype != NULL)
|
||||
tmp_keymgmt = allocated_keymgmt =
|
||||
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, propquery);
|
||||
tmp_keymgmt = ctx->keymgmt;
|
||||
ctx->keymgmt = NULL;
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
}
|
||||
|
||||
@@ -1159,7 +1465,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt)) {
|
||||
if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt, libctx, propquery)) {
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
@@ -1212,98 +1518,255 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* This differs from exporting in that it releases the legacy key and assigns
|
||||
* the export keymgmt and keydata to the "origin" provider side key instead
|
||||
* of the operation cache.
|
||||
*/
|
||||
void *evp_pkey_upgrade_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
|
||||
EVP_KEYMGMT **keymgmt,
|
||||
const char *propquery)
|
||||
int evp_pkey_downgrade(EVP_PKEY *pk)
|
||||
{
|
||||
EVP_KEYMGMT *allocated_keymgmt = NULL;
|
||||
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
||||
void *keydata = NULL;
|
||||
EVP_KEYMGMT *keymgmt = pk->keymgmt;
|
||||
void *keydata = pk->keydata;
|
||||
int type = pk->save_type;
|
||||
const char *keytype = NULL;
|
||||
|
||||
if (pk == NULL)
|
||||
return NULL;
|
||||
/* If this isn't a provider side key, we're done */
|
||||
if (keymgmt == NULL)
|
||||
return 1;
|
||||
|
||||
/* Get the key type name for error reporting */
|
||||
if (type != EVP_PKEY_NONE)
|
||||
keytype = OBJ_nid2sn(type);
|
||||
else
|
||||
keytype =
|
||||
evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id);
|
||||
|
||||
/*
|
||||
* If this key is already "upgraded", this function shouldn't have been
|
||||
* called.
|
||||
* |save_type| was set when any of the EVP_PKEY_set_type functions
|
||||
* was called. It was set to EVP_PKEY_NONE if the key type wasn't
|
||||
* recognised to be any of the legacy key types, and the downgrade
|
||||
* isn't possible.
|
||||
*/
|
||||
if (!ossl_assert(pk->keymgmt == NULL))
|
||||
return NULL;
|
||||
|
||||
if (keymgmt != NULL) {
|
||||
tmp_keymgmt = *keymgmt;
|
||||
*keymgmt = NULL;
|
||||
if (type == EVP_PKEY_NONE) {
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE,
|
||||
"key type = %s, can't downgrade", keytype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the key isn't a legacy one, bail out, but with proper values */
|
||||
if (pk->pkey.ptr == NULL) {
|
||||
tmp_keymgmt = pk->keymgmt;
|
||||
keydata = pk->keydata;
|
||||
} else {
|
||||
/* If the legacy key doesn't have an export function, give up */
|
||||
if (pk->ameth->export_to == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If no keymgmt was given, get a default keymgmt */
|
||||
if (tmp_keymgmt == NULL) {
|
||||
EVP_PKEY_CTX *ctx =
|
||||
EVP_PKEY_CTX_new_from_pkey(libctx, pk, propquery);
|
||||
|
||||
if (ctx != NULL && ctx->keytype != NULL)
|
||||
tmp_keymgmt = allocated_keymgmt =
|
||||
EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, propquery);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
}
|
||||
|
||||
/* If we still don't have a keymgmt, give up */
|
||||
if (tmp_keymgmt == NULL)
|
||||
goto end;
|
||||
|
||||
/* Make sure that the keymgmt key type matches the legacy NID */
|
||||
if (!ossl_assert(EVP_KEYMGMT_is_a(tmp_keymgmt, OBJ_nid2sn(pk->type))))
|
||||
goto end;
|
||||
|
||||
if ((keydata = evp_keymgmt_newdata(tmp_keymgmt)) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!pk->ameth->export_to(pk, keydata, tmp_keymgmt)
|
||||
|| !EVP_KEYMGMT_up_ref(tmp_keymgmt)) {
|
||||
evp_keymgmt_freedata(tmp_keymgmt, keydata);
|
||||
keydata = NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the operation cache, all the legacy data, as well as the
|
||||
* dirty counters
|
||||
*/
|
||||
evp_pkey_free_legacy(pk);
|
||||
pk->dirty_cnt_copy = 0;
|
||||
|
||||
evp_keymgmt_util_clear_operation_cache(pk);
|
||||
pk->keymgmt = tmp_keymgmt;
|
||||
pk->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(pk);
|
||||
}
|
||||
|
||||
end:
|
||||
/*
|
||||
* If nothing was upgraded, |tmp_keymgmt| might point at a freed
|
||||
* EVP_KEYMGMT, so we clear it to be safe. It shouldn't be useful for
|
||||
* the caller either way in that case.
|
||||
* To be able to downgrade, we steal the provider side "origin" keymgmt
|
||||
* and keydata. We've already grabbed the pointers, so all we need to
|
||||
* do is clear those pointers in |pk| and then call evp_pkey_free_it().
|
||||
* That way, we can restore |pk| if we need to.
|
||||
*/
|
||||
if (keydata == NULL)
|
||||
tmp_keymgmt = NULL;
|
||||
pk->keymgmt = NULL;
|
||||
pk->keydata = NULL;
|
||||
evp_pkey_free_it(pk);
|
||||
if (EVP_PKEY_set_type(pk, type)) {
|
||||
/* If the key is typed but empty, we're done */
|
||||
if (keydata == NULL) {
|
||||
/* We're dropping the EVP_KEYMGMT */
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (keymgmt != NULL)
|
||||
*keymgmt = tmp_keymgmt;
|
||||
if (pk->ameth->import_from == NULL) {
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION,
|
||||
"key type = %s", keytype);
|
||||
} else if (evp_keymgmt_export(keymgmt, keydata,
|
||||
OSSL_KEYMGMT_SELECT_ALL,
|
||||
pk->ameth->import_from, pk)) {
|
||||
/*
|
||||
* Save the provider side data in the operation cache, so they'll
|
||||
* find it again. evp_pkey_free_it() cleared the cache, so it's
|
||||
* safe to assume slot zero is free.
|
||||
* Note that evp_keymgmt_util_cache_keydata() increments keymgmt's
|
||||
* reference count.
|
||||
*/
|
||||
evp_keymgmt_util_cache_keydata(pk, 0, keymgmt, keydata);
|
||||
|
||||
EVP_KEYMGMT_free(allocated_keymgmt);
|
||||
return keydata;
|
||||
/* Synchronize the dirty count */
|
||||
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
|
||||
|
||||
/* evp_keymgmt_export() increased the refcount... */
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ERR_raise_data(ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE,
|
||||
"key type = %s", keytype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Something went wrong. This could for example happen if the keymgmt
|
||||
* turns out to be an HSM implementation that refuses to let go of some
|
||||
* of the key data, typically the private bits. In this case, we restore
|
||||
* the provider side internal "origin" and leave it at that.
|
||||
*/
|
||||
if (!ossl_assert(EVP_PKEY_set_type_by_keymgmt(pk, keymgmt))) {
|
||||
/* This should not be impossible */
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
/* EVP_PKEY_set_type_by_keymgmt() increased the refcount... */
|
||||
EVP_KEYMGMT_free(keymgmt);
|
||||
pk->keydata = keydata;
|
||||
evp_keymgmt_util_cache_keyinfo(pk);
|
||||
return 0; /* No downgrade, but at least the key is restored */
|
||||
}
|
||||
#endif /* FIPS_MODE */
|
||||
|
||||
const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
|
||||
{
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL)
|
||||
return 0;
|
||||
return evp_keymgmt_gettable_params(pkey->keymgmt);
|
||||
}
|
||||
|
||||
/*
|
||||
* For the following methods param->return_size is set to a value
|
||||
* larger than can be returned by the call to evp_keymgmt_get_params().
|
||||
* If it is still this value then the parameter was ignored - and in this
|
||||
* case it returns an error..
|
||||
*/
|
||||
|
||||
int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn)
|
||||
{
|
||||
int ret = 0;
|
||||
OSSL_PARAM params[2];
|
||||
unsigned char buffer[2048];
|
||||
/*
|
||||
* Use -1 as the terminator here instead of sizeof(buffer) + 1 since
|
||||
* -1 is less likely to be a valid value.
|
||||
*/
|
||||
const size_t not_set = (size_t)-1;
|
||||
unsigned char *buf = NULL;
|
||||
size_t buf_sz = 0;
|
||||
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL
|
||||
|| key_name == NULL
|
||||
|| bn == NULL)
|
||||
return 0;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
|
||||
/* If the return_size is still not_set then we know it was not found */
|
||||
params[0].return_size = not_set;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) {
|
||||
if (params[0].return_size == not_set
|
||||
|| params[0].return_size == 0)
|
||||
return 0;
|
||||
buf_sz = params[0].return_size;
|
||||
/*
|
||||
* If it failed because the buffer was too small then allocate the
|
||||
* required buffer size and retry.
|
||||
*/
|
||||
buf = OPENSSL_zalloc(buf_sz);
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
params[0].data = buf;
|
||||
params[0].data_size = buf_sz;
|
||||
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
goto err;
|
||||
}
|
||||
/* Fail if the param was not found */
|
||||
if (params[0].return_size == not_set)
|
||||
goto err;
|
||||
ret = OSSL_PARAM_get_BN(params, bn);
|
||||
err:
|
||||
OPENSSL_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
|
||||
unsigned char *buf, size_t max_buf_sz,
|
||||
size_t *out_sz)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
const size_t not_set = max_buf_sz + 1;
|
||||
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL
|
||||
|| key_name == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
|
||||
params[0].return_size = not_set;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
if (params[0].return_size == not_set)
|
||||
return 0;
|
||||
if (out_sz != NULL)
|
||||
*out_sz = params[0].return_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
|
||||
char *str, size_t max_buf_sz,
|
||||
size_t *out_sz)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
const size_t not_set = max_buf_sz + 1;
|
||||
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL
|
||||
|| key_name == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
|
||||
params[0].return_size = not_set;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
if (params[0].return_size == not_set)
|
||||
return 0;
|
||||
if (out_sz != NULL)
|
||||
*out_sz = params[0].return_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
const size_t not_set = sizeof(int) + 1;
|
||||
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL
|
||||
|| key_name == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] = OSSL_PARAM_construct_int(key_name, out);
|
||||
params[0].return_size = not_set;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
if (params[0].return_size == not_set)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out)
|
||||
{
|
||||
OSSL_PARAM params[2];
|
||||
const size_t not_set = sizeof(size_t) + 1;
|
||||
|
||||
if (pkey == NULL
|
||||
|| pkey->keymgmt == NULL
|
||||
|| pkey->keydata == NULL
|
||||
|| key_name == NULL)
|
||||
return 0;
|
||||
|
||||
params[0] = OSSL_PARAM_construct_size_t(key_name, out);
|
||||
params[0].return_size = not_set;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
|
||||
return 0;
|
||||
if (params[0].return_size == not_set)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
+79
-9
@@ -51,17 +51,31 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
|
||||
MAC_PKEY_CTX *hctx;
|
||||
/* We're being smart and using the same base NIDs for PKEY and for MAC */
|
||||
int nid = ctx->pmeth->pkey_id;
|
||||
EVP_MAC *mac = EVP_MAC_fetch(NULL, OBJ_nid2sn(nid), NULL);
|
||||
EVP_MAC *mac;
|
||||
|
||||
ERR_set_mark();
|
||||
mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
|
||||
ERR_pop_to_mark();
|
||||
|
||||
/*
|
||||
* mac == NULL may actually be ok in some situations. In an
|
||||
* EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
|
||||
* default libctx. We don't actually need the underlying MAC to be present
|
||||
* to successfully set the key in that case. The resulting EVP_PKEY could
|
||||
* then be used in some other libctx where the MAC *is* present
|
||||
*/
|
||||
|
||||
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
|
||||
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||
if (hctx->ctx == NULL) {
|
||||
OPENSSL_free(hctx);
|
||||
return 0;
|
||||
if (mac != NULL) {
|
||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||
if (hctx->ctx == NULL) {
|
||||
OPENSSL_free(hctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (nid == EVP_PKEY_CMAC) {
|
||||
@@ -83,6 +97,13 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||
MAC_PKEY_CTX *sctx, *dctx;
|
||||
|
||||
sctx = EVP_PKEY_CTX_get_data(src);
|
||||
|
||||
if (sctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sctx->ctx->data == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -142,7 +163,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
|
||||
|
||||
if (hctx != NULL) {
|
||||
EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
|
||||
EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
|
||||
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
@@ -177,8 +198,15 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
break;
|
||||
case MAC_TYPE_MAC:
|
||||
{
|
||||
EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
||||
EVP_MAC_CTX *cmkey;
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
||||
if (cmkey == NULL)
|
||||
return 0;
|
||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
|
||||
@@ -220,6 +248,12 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||
hctx->type == MAC_TYPE_RAW
|
||||
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (set_key) {
|
||||
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
||||
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
||||
@@ -285,6 +319,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
ciphname, 0);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
||||
|| !EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
@@ -306,8 +348,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
|
||||
if (ctx->pkey == NULL)
|
||||
return 0;
|
||||
new_mac_ctx = EVP_MAC_CTX_dup((EVP_MAC_CTX *)ctx->pkey
|
||||
->pkey.ptr);
|
||||
new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr);
|
||||
if (new_mac_ctx == NULL)
|
||||
return 0;
|
||||
EVP_MAC_CTX_free(hctx->ctx);
|
||||
@@ -337,6 +378,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
params[0] =
|
||||
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
|
||||
return 0;
|
||||
|
||||
@@ -373,6 +422,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
p2, p1);
|
||||
params[params_n] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/*
|
||||
* This actually means the fetch failed during the init call
|
||||
*/
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
}
|
||||
break;
|
||||
@@ -385,6 +442,12 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
case EVP_PKEY_CTRL_DIGESTINIT:
|
||||
switch (hctx->type) {
|
||||
case MAC_TYPE_RAW:
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ensure that we have attached the implementation */
|
||||
if (!EVP_MAC_init(hctx->ctx))
|
||||
return 0;
|
||||
@@ -456,6 +519,13 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
type, value, strlen(value) + 1, NULL))
|
||||
return 0;
|
||||
params[1] = OSSL_PARAM_construct_end();
|
||||
|
||||
if (hctx->ctx == NULL) {
|
||||
/* This actually means the fetch failed during the init call */
|
||||
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||
OPENSSL_free(params[0].data);
|
||||
return ok;
|
||||
|
||||
+33
-16
@@ -35,19 +35,24 @@ int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
OSSL_KEYMGMT_SELECT_PUBLIC_KEY);
|
||||
|
||||
if (pkey->type == EVP_PKEY_NONE)
|
||||
goto not_supported;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* legacy */
|
||||
/* call customized public key check function first */
|
||||
if (ctx->pmeth->public_check != NULL)
|
||||
return ctx->pmeth->public_check(pkey);
|
||||
|
||||
/* use default public key check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL)
|
||||
goto not_supported;
|
||||
|
||||
return pkey->ameth->pkey_public_check(pkey);
|
||||
#endif
|
||||
not_supported:
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
|
||||
@@ -68,19 +73,24 @@ int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
|
||||
if (pkey->type == EVP_PKEY_NONE)
|
||||
goto not_supported;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* legacy */
|
||||
/* call customized param check function first */
|
||||
if (ctx->pmeth->param_check != NULL)
|
||||
return ctx->pmeth->param_check(pkey);
|
||||
|
||||
/* legacy */
|
||||
/* use default param check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL)
|
||||
goto not_supported;
|
||||
|
||||
return pkey->ameth->pkey_param_check(pkey);
|
||||
#endif
|
||||
not_supported:
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
|
||||
@@ -101,6 +111,7 @@ int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
|
||||
return evp_keymgmt_validate(keymgmt, key,
|
||||
OSSL_KEYMGMT_SELECT_PRIVATE_KEY);
|
||||
/* not supported for legacy keys */
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -121,6 +132,7 @@ int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_KEYPAIR);
|
||||
/* not supported for legacy keys */
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -141,18 +153,23 @@ int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
|
||||
if (key != NULL && keymgmt != NULL)
|
||||
return evp_keymgmt_validate(keymgmt, key, OSSL_KEYMGMT_SELECT_ALL);
|
||||
|
||||
if (pkey->type == EVP_PKEY_NONE)
|
||||
goto not_supported;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* legacy */
|
||||
/* call customized check function first */
|
||||
if (ctx->pmeth->check != NULL)
|
||||
return ctx->pmeth->check(pkey);
|
||||
|
||||
/* use default check function in ameth */
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_CHECK,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL)
|
||||
goto not_supported;
|
||||
|
||||
return pkey->ameth->pkey_check(pkey);
|
||||
#endif
|
||||
not_supported:
|
||||
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
*/
|
||||
ERR_set_mark();
|
||||
|
||||
if (ctx->keytype == NULL || ctx->engine != NULL)
|
||||
if (ctx->engine != NULL || ctx->keytype == NULL)
|
||||
goto legacy;
|
||||
|
||||
/*
|
||||
|
||||
+238
-76
@@ -9,7 +9,10 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/core.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/core.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/bn.h"
|
||||
@@ -17,102 +20,262 @@
|
||||
#include "crypto/evp.h"
|
||||
#include "evp_local.h"
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
|
||||
#if !defined(FIPS_MODE) && !defined(OPENSSL_NO_EC)
|
||||
# define TMP_SM2_HACK
|
||||
#endif
|
||||
|
||||
/* TODO(3.0) remove when provider SM2 key generation is implemented */
|
||||
#ifdef TMP_SM2_HACK
|
||||
# include <openssl/ec.h>
|
||||
# include <openssl/serializer.h>
|
||||
# include "internal/sizes.h"
|
||||
#endif
|
||||
|
||||
static int gen_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
int ret = 0;
|
||||
|
||||
if (ctx == NULL)
|
||||
goto not_supported;
|
||||
|
||||
evp_pkey_ctx_free_old_ops(ctx);
|
||||
ctx->operation = operation;
|
||||
|
||||
if (ctx->keymgmt == NULL || ctx->keymgmt->gen_init == NULL)
|
||||
goto legacy;
|
||||
|
||||
/* TODO remove when provider SM2 key generation is implemented */
|
||||
#ifdef TMP_SM2_HACK
|
||||
if (ctx->pmeth != NULL && ctx->pmeth->pkey_id == EVP_PKEY_SM2)
|
||||
goto legacy;
|
||||
#endif
|
||||
|
||||
switch (operation) {
|
||||
case EVP_PKEY_OP_PARAMGEN:
|
||||
ctx->op.keymgmt.genctx =
|
||||
evp_keymgmt_gen_init(ctx->keymgmt,
|
||||
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
|
||||
break;
|
||||
case EVP_PKEY_OP_KEYGEN:
|
||||
ctx->op.keymgmt.genctx =
|
||||
evp_keymgmt_gen_init(ctx->keymgmt, OSSL_KEYMGMT_SELECT_KEYPAIR);
|
||||
break;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_PARAMGEN;
|
||||
if (!ctx->pmeth->paramgen_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->paramgen_init(ctx);
|
||||
|
||||
if (ctx->op.keymgmt.genctx == NULL)
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
|
||||
else
|
||||
ret = 1;
|
||||
goto end;
|
||||
|
||||
legacy:
|
||||
#ifdef FIPS_MODE
|
||||
goto not_supported;
|
||||
#else
|
||||
if (ctx->pmeth == NULL
|
||||
|| (operation == EVP_PKEY_OP_PARAMGEN
|
||||
&& ctx->pmeth->paramgen == NULL)
|
||||
|| (operation == EVP_PKEY_OP_KEYGEN
|
||||
&& ctx->pmeth->keygen == NULL))
|
||||
goto not_supported;
|
||||
|
||||
ret = 1;
|
||||
switch (operation) {
|
||||
case EVP_PKEY_OP_PARAMGEN:
|
||||
if (ctx->pmeth->paramgen_init != NULL)
|
||||
ret = ctx->pmeth->paramgen_init(ctx);
|
||||
break;
|
||||
case EVP_PKEY_OP_KEYGEN:
|
||||
if (ctx->pmeth->keygen_init != NULL)
|
||||
ret = ctx->pmeth->keygen_init(ctx);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
|
||||
not_supported:
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
ret = -2;
|
||||
goto end;
|
||||
}
|
||||
|
||||
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ppkey == NULL)
|
||||
return -1;
|
||||
|
||||
if (*ppkey == NULL)
|
||||
*ppkey = EVP_PKEY_new();
|
||||
|
||||
if (*ppkey == NULL) {
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ctx->pmeth->paramgen(ctx, *ppkey);
|
||||
if (ret <= 0) {
|
||||
EVP_PKEY_free(*ppkey);
|
||||
*ppkey = NULL;
|
||||
}
|
||||
return ret;
|
||||
return gen_init(ctx, EVP_PKEY_OP_PARAMGEN);
|
||||
}
|
||||
|
||||
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_KEYGEN;
|
||||
if (!ctx->pmeth->keygen_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->keygen_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
return gen_init(ctx, EVP_PKEY_OP_KEYGEN);
|
||||
}
|
||||
|
||||
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
static int ossl_callback_to_pkey_gencb(const OSSL_PARAM params[], void *arg)
|
||||
{
|
||||
int ret;
|
||||
EVP_PKEY_CTX *ctx = arg;
|
||||
const OSSL_PARAM *param = NULL;
|
||||
int p = -1, n = -1;
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
if (ctx->pkey_gencb == NULL)
|
||||
return 1; /* No callback? That's fine */
|
||||
|
||||
if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_POTENTIAL))
|
||||
== NULL
|
||||
|| !OSSL_PARAM_get_int(param, &p))
|
||||
return 0;
|
||||
if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_ITERATION))
|
||||
== NULL
|
||||
|| !OSSL_PARAM_get_int(param, &n))
|
||||
return 0;
|
||||
|
||||
ctx->keygen_info[0] = p;
|
||||
ctx->keygen_info[1] = n;
|
||||
|
||||
return ctx->pkey_gencb(ctx);
|
||||
}
|
||||
|
||||
int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
{
|
||||
int ret = 0;
|
||||
OSSL_CALLBACK cb;
|
||||
EVP_PKEY *allocated_pkey = NULL;
|
||||
|
||||
if (ppkey == NULL)
|
||||
return -1;
|
||||
|
||||
if (*ppkey == NULL)
|
||||
*ppkey = EVP_PKEY_new();
|
||||
if (*ppkey == NULL)
|
||||
return -1;
|
||||
if (ctx == NULL)
|
||||
goto not_supported;
|
||||
|
||||
ret = ctx->pmeth->keygen(ctx, *ppkey);
|
||||
if ((ctx->operation & EVP_PKEY_OP_TYPE_GEN) == 0)
|
||||
goto not_initialized;
|
||||
|
||||
if (*ppkey == NULL)
|
||||
*ppkey = allocated_pkey = EVP_PKEY_new();
|
||||
|
||||
if (*ppkey == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ctx->op.keymgmt.genctx == NULL)
|
||||
goto legacy;
|
||||
|
||||
ret = 1;
|
||||
if (ctx->pkey != NULL) {
|
||||
EVP_KEYMGMT *tmp_keymgmt = ctx->keymgmt;
|
||||
void *keydata =
|
||||
evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
|
||||
&tmp_keymgmt, ctx->propquery);
|
||||
|
||||
if (keydata == NULL)
|
||||
goto not_supported;
|
||||
ret = evp_keymgmt_gen_set_template(ctx->keymgmt,
|
||||
ctx->op.keymgmt.genctx, keydata);
|
||||
}
|
||||
|
||||
/*
|
||||
* the returned value from evp_keymgmt_util_gen() is cached in *ppkey,
|
||||
* so we so not need to save it, just check it.
|
||||
*/
|
||||
ret = ret
|
||||
&& (evp_keymgmt_util_gen(*ppkey, ctx->keymgmt, ctx->op.keymgmt.genctx,
|
||||
ossl_callback_to_pkey_gencb, ctx)
|
||||
!= NULL);
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* In case |*ppkey| was originally a legacy key */
|
||||
if (ret)
|
||||
evp_pkey_free_legacy(*ppkey);
|
||||
#endif
|
||||
|
||||
/* TODO remove when SM2 key have been cleanly separated from EC keys */
|
||||
#ifdef TMP_SM2_HACK
|
||||
/*
|
||||
* Legacy SM2 keys are implemented as EC_KEY with a twist. The legacy
|
||||
* key generation detects the SM2 curve and "magically" changes the pkey
|
||||
* id accordingly.
|
||||
* Since we don't have SM2 in the provider implementation, we need to
|
||||
* downgrade the generated provider side key to a legacy one under the
|
||||
* same conditions.
|
||||
*
|
||||
* THIS IS AN UGLY BUT TEMPORARY HACK
|
||||
*/
|
||||
{
|
||||
char curve_name[OSSL_MAX_NAME_SIZE] = "";
|
||||
|
||||
if (EVP_PKEY_CTX_get_ec_paramgen_curve_name(ctx, curve_name,
|
||||
sizeof(curve_name)) < 1
|
||||
|| strcmp(curve_name, "SM2") != 0)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!evp_pkey_downgrade(*ppkey)
|
||||
|| !EVP_PKEY_set_alias_type(*ppkey, EVP_PKEY_SM2))
|
||||
ret = 0;
|
||||
#endif
|
||||
goto end;
|
||||
|
||||
legacy:
|
||||
#ifdef FIPS_MODE
|
||||
goto not_supported;
|
||||
#else
|
||||
if (ctx->pkey && !evp_pkey_downgrade(ctx->pkey))
|
||||
goto not_accessible;
|
||||
switch (ctx->operation) {
|
||||
case EVP_PKEY_OP_PARAMGEN:
|
||||
ret = ctx->pmeth->paramgen(ctx, *ppkey);
|
||||
break;
|
||||
case EVP_PKEY_OP_KEYGEN:
|
||||
ret = ctx->pmeth->keygen(ctx, *ppkey);
|
||||
break;
|
||||
default:
|
||||
goto not_supported;
|
||||
}
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (ret <= 0) {
|
||||
EVP_PKEY_free(*ppkey);
|
||||
*ppkey = NULL;
|
||||
if (allocated_pkey != NULL)
|
||||
*ppkey = NULL;
|
||||
EVP_PKEY_free(allocated_pkey);
|
||||
}
|
||||
return ret;
|
||||
|
||||
not_supported:
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
ret = -2;
|
||||
goto end;
|
||||
not_initialized:
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
ret = -1;
|
||||
goto end;
|
||||
#ifndef FIPS_MODE
|
||||
not_accessible:
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS);
|
||||
ret = -1;
|
||||
goto end;
|
||||
#endif
|
||||
}
|
||||
|
||||
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
{
|
||||
if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
return EVP_PKEY_gen(ctx, ppkey);
|
||||
}
|
||||
|
||||
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
{
|
||||
if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
return EVP_PKEY_gen(ctx, ppkey);
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
|
||||
@@ -152,6 +315,8 @@ int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
|
||||
return ctx->keygen_info[idx];
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
|
||||
const unsigned char *key, int keylen)
|
||||
{
|
||||
@@ -181,13 +346,10 @@ static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
goto not_supported;
|
||||
|
||||
evp_pkey_ctx_free_old_ops(ctx);
|
||||
ctx->operation = operation;
|
||||
if (ctx->keymgmt == NULL)
|
||||
ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype,
|
||||
ctx->propquery);
|
||||
if (ctx->keymgmt == NULL)
|
||||
goto not_supported;
|
||||
|
||||
ctx->operation = operation;
|
||||
return 1;
|
||||
|
||||
not_supported:
|
||||
|
||||
+98
-24
@@ -1,4 +1,3 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
@@ -138,12 +137,13 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
|
||||
|
||||
static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
EVP_PKEY *pkey, ENGINE *e,
|
||||
const char *name, const char *propquery,
|
||||
const char *keytype, const char *propquery,
|
||||
int id)
|
||||
|
||||
{
|
||||
EVP_PKEY_CTX *ret;
|
||||
const EVP_PKEY_METHOD *pmeth = NULL;
|
||||
EVP_KEYMGMT *keymgmt = NULL;
|
||||
|
||||
/*
|
||||
* When using providers, the context is bound to the algo implementation
|
||||
@@ -156,15 +156,11 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
* If the key doesn't contain anything legacy, then it must be provided,
|
||||
* so we extract the necessary information and use that.
|
||||
*/
|
||||
if (pkey != NULL && pkey->ameth == NULL) {
|
||||
if (pkey != NULL && pkey->type == EVP_PKEY_NONE) {
|
||||
/* If we have an engine, something went wrong somewhere... */
|
||||
if (!ossl_assert(e == NULL))
|
||||
return NULL;
|
||||
name = evp_first_name(pkey->keymgmt->prov, pkey->keymgmt->name_id);
|
||||
/*
|
||||
* TODO: I wonder if the EVP_PKEY should have the name and propquery
|
||||
* that were used when building it.... /RL
|
||||
*/
|
||||
keytype = evp_first_name(pkey->keymgmt->prov, pkey->keymgmt->name_id);
|
||||
goto common;
|
||||
}
|
||||
#ifndef FIPS_MODE
|
||||
@@ -187,10 +183,10 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
* since that can only happen internally, it's safe to make an
|
||||
* assertion.
|
||||
*/
|
||||
if (!ossl_assert(e == NULL || name == NULL))
|
||||
if (!ossl_assert(e == NULL || keytype == NULL))
|
||||
return NULL;
|
||||
if (e == NULL)
|
||||
name = OBJ_nid2sn(id);
|
||||
keytype = OBJ_nid2sn(id);
|
||||
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
if (e == NULL && pkey != NULL)
|
||||
@@ -225,6 +221,17 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
/* END legacy */
|
||||
#endif /* FIPS_MODE */
|
||||
common:
|
||||
/*
|
||||
* If there's no engine and there's a name, we try fetching a provider
|
||||
* implementation.
|
||||
*/
|
||||
if (e == NULL && keytype != NULL) {
|
||||
/* This could fail so ignore errors */
|
||||
ERR_set_mark();
|
||||
keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
|
||||
ERR_pop_to_mark();
|
||||
}
|
||||
|
||||
ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
if (ret == NULL) {
|
||||
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
|
||||
@@ -234,8 +241,9 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
|
||||
return NULL;
|
||||
}
|
||||
ret->libctx = libctx;
|
||||
ret->keytype = name;
|
||||
ret->propquery = propquery;
|
||||
ret->keytype = keytype;
|
||||
ret->keymgmt = keymgmt;
|
||||
ret->engine = e;
|
||||
ret->pmeth = pmeth;
|
||||
ret->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
@@ -292,6 +300,9 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
|
||||
EVP_ASYM_CIPHER_free(ctx->op.ciph.cipher);
|
||||
ctx->op.ciph.ciphprovctx = NULL;
|
||||
ctx->op.ciph.cipher = NULL;
|
||||
} else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
if (ctx->op.keymgmt.genctx != NULL && ctx->keymgmt != NULL)
|
||||
evp_keymgmt_gen_cleanup(ctx->keymgmt, ctx->op.keymgmt.genctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -569,6 +580,12 @@ int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
&& ctx->op.ciph.cipher->set_ctx_params != NULL)
|
||||
return ctx->op.ciph.cipher->set_ctx_params(ctx->op.ciph.ciphprovctx,
|
||||
params);
|
||||
if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
||||
&& ctx->op.keymgmt.genctx != NULL
|
||||
&& ctx->keymgmt != NULL
|
||||
&& ctx->keymgmt->gen_set_params != NULL)
|
||||
return evp_keymgmt_gen_set_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -593,6 +610,12 @@ int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params)
|
||||
&& ctx->op.ciph.cipher->get_ctx_params != NULL)
|
||||
return ctx->op.ciph.cipher->get_ctx_params(ctx->op.ciph.ciphprovctx,
|
||||
params);
|
||||
if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
||||
&& ctx->op.keymgmt.genctx != NULL
|
||||
&& ctx->keymgmt != NULL
|
||||
&& ctx->keymgmt->gen_get_params != NULL)
|
||||
return evp_keymgmt_gen_get_params(ctx->keymgmt, ctx->op.keymgmt.genctx,
|
||||
params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -629,6 +652,10 @@ const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx)
|
||||
&& ctx->op.ciph.cipher != NULL
|
||||
&& ctx->op.ciph.cipher->settable_ctx_params != NULL)
|
||||
return ctx->op.ciph.cipher->settable_ctx_params();
|
||||
if (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
||||
&& ctx->keymgmt != NULL
|
||||
&& ctx->keymgmt->gen_settable_params != NULL)
|
||||
return evp_keymgmt_gen_settable_params(ctx->keymgmt);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -792,6 +819,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
# ifndef OPENSSL_NO_EC
|
||||
if (keytype == EVP_PKEY_EC) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, p1);
|
||||
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
|
||||
if (p1 == -2) {
|
||||
return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx);
|
||||
@@ -822,6 +851,30 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
}
|
||||
}
|
||||
# endif
|
||||
if (keytype == EVP_PKEY_RSA) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
|
||||
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
|
||||
return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, p1);
|
||||
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
|
||||
return EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES:
|
||||
return EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, p1);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* keytype == -1 is used when several key types share the same structure,
|
||||
* or for generic controls that are the same across multiple key types.
|
||||
*/
|
||||
if (keytype == -1) {
|
||||
switch (cmd) {
|
||||
case EVP_PKEY_CTRL_MD:
|
||||
@@ -832,18 +885,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
return EVP_PKEY_CTX_set_rsa_padding(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_PADDING:
|
||||
return EVP_PKEY_CTX_get_rsa_padding(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
|
||||
return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2);
|
||||
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
|
||||
return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2);
|
||||
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
|
||||
return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, p1);
|
||||
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
|
||||
@@ -854,7 +897,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
case EVP_PKEY_CTRL_CMS_DECRYPT:
|
||||
case EVP_PKEY_CTRL_CMS_ENCRYPT:
|
||||
# endif
|
||||
if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
|
||||
/* TODO (3.0) Temporary hack, this should probe */
|
||||
if (!EVP_PKEY_is_a(EVP_PKEY_CTX_get0_pkey(ctx), "RSASSA-PSS"))
|
||||
return 1;
|
||||
ERR_raise(ERR_LIB_EVP,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
@@ -878,7 +922,9 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
&& ctx->op.ciph.ciphprovctx != NULL))
|
||||
&& ctx->op.ciph.ciphprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
||||
&& ctx->op.keymgmt.genctx != NULL))
|
||||
return legacy_ctrl_to_param(ctx, keytype, optype, cmd, p1, p2);
|
||||
|
||||
if (ctx->pmeth == NULL || ctx->pmeth->ctrl == NULL) {
|
||||
@@ -920,6 +966,24 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
const char *value)
|
||||
{
|
||||
|
||||
/* Special cases that we intercept */
|
||||
# ifndef OPENSSL_NO_EC
|
||||
/*
|
||||
* We don't support encoding settings for providers, i.e. the only
|
||||
* possible encoding is "named_curve", so we simply fail when something
|
||||
* else is given, and otherwise just pretend all is fine.
|
||||
*/
|
||||
if (strcmp(name, "ec_param_enc") == 0) {
|
||||
if (strcmp(value, "named_curve") == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
if (strcmp(name, "rsa_padding_mode") == 0)
|
||||
name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE;
|
||||
else if (strcmp(name, "rsa_mgf1_md") == 0)
|
||||
@@ -930,11 +994,19 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL;
|
||||
else if (strcmp(name, "rsa_pss_saltlen") == 0)
|
||||
name = OSSL_SIGNATURE_PARAM_PSS_SALTLEN;
|
||||
else if (strcmp(name, "rsa_keygen_bits") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_BITS;
|
||||
else if (strcmp(name, "rsa_keygen_pubexp") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_E;
|
||||
else if (strcmp(name, "rsa_keygen_primes") == 0)
|
||||
name = OSSL_PKEY_PARAM_RSA_PRIMES;
|
||||
# ifndef OPENSSL_NO_DH
|
||||
else if (strcmp(name, "dh_pad") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_PAD;
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EC
|
||||
else if (strcmp(name, "ec_paramgen_curve") == 0)
|
||||
name = OSSL_PKEY_PARAM_EC_NAME;
|
||||
else if (strcmp(name, "ecdh_cofactor_mode") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
|
||||
else if (strcmp(name, "ecdh_kdf_md") == 0)
|
||||
@@ -979,7 +1051,9 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
|| (EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx)
|
||||
&& ctx->op.sig.sigprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
|
||||
&& ctx->op.ciph.ciphprovctx != NULL))
|
||||
&& ctx->op.ciph.ciphprovctx != NULL)
|
||||
|| (EVP_PKEY_CTX_IS_GEN_OP(ctx)
|
||||
&& ctx->op.keymgmt.genctx != NULL))
|
||||
return legacy_ctrl_str_to_param(ctx, name, value);
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
|
||||
|
||||
+27
-7
@@ -105,7 +105,6 @@ static void *evp_signature_from_dispatch(int name_id,
|
||||
break;
|
||||
signature->digest_sign_init
|
||||
= OSSL_get_OP_signature_digest_sign_init(fns);
|
||||
digsignfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE:
|
||||
if (signature->digest_sign_update != NULL)
|
||||
@@ -121,12 +120,17 @@ static void *evp_signature_from_dispatch(int name_id,
|
||||
= OSSL_get_OP_signature_digest_sign_final(fns);
|
||||
digsignfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DIGEST_SIGN:
|
||||
if (signature->digest_sign != NULL)
|
||||
break;
|
||||
signature->digest_sign
|
||||
= OSSL_get_OP_signature_digest_sign(fns);
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT:
|
||||
if (signature->digest_verify_init != NULL)
|
||||
break;
|
||||
signature->digest_verify_init
|
||||
= OSSL_get_OP_signature_digest_verify_init(fns);
|
||||
digverifyfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE:
|
||||
if (signature->digest_verify_update != NULL)
|
||||
@@ -142,6 +146,12 @@ static void *evp_signature_from_dispatch(int name_id,
|
||||
= OSSL_get_OP_signature_digest_verify_final(fns);
|
||||
digverifyfncnt++;
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_DIGEST_VERIFY:
|
||||
if (signature->digest_verify != NULL)
|
||||
break;
|
||||
signature->digest_verify
|
||||
= OSSL_get_OP_signature_digest_verify(fns);
|
||||
break;
|
||||
case OSSL_FUNC_SIGNATURE_FREECTX:
|
||||
if (signature->freectx != NULL)
|
||||
break;
|
||||
@@ -216,12 +226,20 @@ static void *evp_signature_from_dispatch(int name_id,
|
||||
&& verifyfncnt == 0
|
||||
&& verifyrecfncnt == 0
|
||||
&& digsignfncnt == 0
|
||||
&& digverifyfncnt == 0)
|
||||
&& digverifyfncnt == 0
|
||||
&& signature->digest_sign == NULL
|
||||
&& signature->digest_verify == NULL)
|
||||
|| (signfncnt != 0 && signfncnt != 2)
|
||||
|| (verifyfncnt != 0 && verifyfncnt != 2)
|
||||
|| (verifyrecfncnt != 0 && verifyrecfncnt != 2)
|
||||
|| (digsignfncnt != 0 && digsignfncnt != 3)
|
||||
|| (digverifyfncnt != 0 && digverifyfncnt != 3)
|
||||
|| (digsignfncnt != 0 && digsignfncnt != 2)
|
||||
|| (digsignfncnt == 2 && signature->digest_sign_init == NULL)
|
||||
|| (digverifyfncnt != 0 && digverifyfncnt != 2)
|
||||
|| (digverifyfncnt == 2 && signature->digest_verify_init == NULL)
|
||||
|| (signature->digest_sign != NULL
|
||||
&& signature->digest_sign_init == NULL)
|
||||
|| (signature->digest_verify != NULL
|
||||
&& signature->digest_verify_init == NULL)
|
||||
|| (gparamfncnt != 0 && gparamfncnt != 2)
|
||||
|| (sparamfncnt != 0 && sparamfncnt != 2)
|
||||
|| (gmdparamfncnt != 0 && gmdparamfncnt != 2)
|
||||
@@ -234,7 +252,9 @@ static void *evp_signature_from_dispatch(int name_id,
|
||||
* (verify_init verify) or
|
||||
* (verify_recover_init, verify_recover) or
|
||||
* (digest_sign_init, digest_sign_update, digest_sign_final) or
|
||||
* (digest_verify_init, digest_verify_update, digest_verify_final).
|
||||
* (digest_verify_init, digest_verify_update, digest_verify_final) or
|
||||
* (digest_sign_init, digest_sign) or
|
||||
* (digest_verify_init, digest_verify).
|
||||
*
|
||||
* set_ctx_params and settable_ctx_params are optional, but if one of
|
||||
* them is present then the other one must also be present. The same
|
||||
@@ -339,7 +359,7 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation)
|
||||
*/
|
||||
ERR_set_mark();
|
||||
|
||||
if (ctx->keytype == NULL)
|
||||
if (ctx->keymgmt == NULL)
|
||||
goto legacy;
|
||||
|
||||
/*
|
||||
|
||||
+26
-23
@@ -24,19 +24,18 @@ int do_ex_data_init(OPENSSL_CTX *ctx)
|
||||
/*
|
||||
* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
|
||||
* a given class. On success, *holds the lock.*
|
||||
* The |global| parameter is assumed to be non null (checked by the caller).
|
||||
*/
|
||||
static EX_CALLBACKS *get_and_lock(OPENSSL_CTX *ctx, int class_index)
|
||||
static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index)
|
||||
{
|
||||
EX_CALLBACKS *ip;
|
||||
OSSL_EX_DATA_GLOBAL *global = NULL;
|
||||
|
||||
if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
|
||||
CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
global = openssl_ctx_get_ex_data_global(ctx);
|
||||
if (global == NULL || global->ex_data_lock == NULL) {
|
||||
if (global->ex_data_lock == NULL) {
|
||||
/*
|
||||
* If we get here, someone (who?) cleaned up the lock, so just
|
||||
* treat it as an error.
|
||||
@@ -111,9 +110,10 @@ int crypto_free_ex_index_ex(OPENSSL_CTX *ctx, int class_index, int idx)
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
|
||||
if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
|
||||
goto err;
|
||||
a = sk_EX_CALLBACK_value(ip->meth, idx);
|
||||
@@ -149,7 +149,7 @@ int crypto_get_ex_new_index_ex(OPENSSL_CTX *ctx, int class_index, long argl,
|
||||
if (global == NULL)
|
||||
return -1;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
return -1;
|
||||
|
||||
@@ -216,13 +216,12 @@ int crypto_new_ex_data_ex(OPENSSL_CTX *ctx, int class_index, void *obj,
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(ctx, class_index);
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
|
||||
ad->ctx = ctx;
|
||||
ad->sk = NULL;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
if (mx > 0) {
|
||||
if (mx < (int)OSSL_NELEM(stack))
|
||||
@@ -269,16 +268,19 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
|
||||
EX_CALLBACK **storage = NULL;
|
||||
EX_CALLBACKS *ip;
|
||||
int toret = 0;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(from->ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
OSSL_EX_DATA_GLOBAL *global;
|
||||
|
||||
to->ctx = from->ctx;
|
||||
if (from->sk == NULL)
|
||||
/* Nothing to copy over */
|
||||
return 1;
|
||||
if ((ip = get_and_lock(from->ctx, class_index)) == NULL)
|
||||
|
||||
global = openssl_ctx_get_ex_data_global(from->ctx);
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
@@ -340,14 +342,15 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
|
||||
EX_CALLBACK *f;
|
||||
EX_CALLBACK *stack[10];
|
||||
EX_CALLBACK **storage = NULL;
|
||||
OSSL_EX_DATA_GLOBAL *global;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
|
||||
if ((ip = get_and_lock(ad->ctx, class_index)) == NULL)
|
||||
goto err;
|
||||
global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
if (global == NULL)
|
||||
goto err;
|
||||
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
goto err;
|
||||
|
||||
mx = sk_EX_CALLBACK_num(ip->meth);
|
||||
if (mx > 0) {
|
||||
if (mx < (int)OSSL_NELEM(stack))
|
||||
@@ -392,18 +395,18 @@ int CRYPTO_alloc_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad,
|
||||
EX_CALLBACK *f;
|
||||
EX_CALLBACKS *ip;
|
||||
void *curval;
|
||||
OSSL_EX_DATA_GLOBAL *global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
OSSL_EX_DATA_GLOBAL *global;
|
||||
|
||||
curval = CRYPTO_get_ex_data(ad, idx);
|
||||
|
||||
/* Already there, no need to allocate */
|
||||
if (curval != NULL)
|
||||
return 1;
|
||||
|
||||
ip = get_and_lock(ad->ctx, class_index);
|
||||
global = openssl_ctx_get_ex_data_global(ad->ctx);
|
||||
if (global == NULL)
|
||||
return 0;
|
||||
|
||||
ip = get_and_lock(global, class_index);
|
||||
if (ip == NULL)
|
||||
return 0;
|
||||
f = sk_EX_CALLBACK_value(ip->meth, idx);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LIBS=../../libcrypto
|
||||
|
||||
$COMMON=ffc_params.c ffc_params_generate.c ffc_key_generate.c\
|
||||
ffc_params_validate.c ffc_key_validate.c
|
||||
ffc_params_validate.c ffc_key_validate.c ffc_backend.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2020 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 <openssl/core_names.h>
|
||||
#include "internal/ffc.h"
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ffc_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_p, *param_q, *param_g;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL;
|
||||
|
||||
if (ffc == NULL)
|
||||
return 0;
|
||||
|
||||
param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_P);
|
||||
param_q = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_Q);
|
||||
param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_G);
|
||||
|
||||
if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p))
|
||||
|| (param_q != NULL && !OSSL_PARAM_get_BN(param_q, &q))
|
||||
|| (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)))
|
||||
goto err;
|
||||
|
||||
ffc_params_set0_pqg(ffc, p, q, g);
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(g);
|
||||
return 0;
|
||||
}
|
||||
+68
-45
@@ -21,7 +21,7 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/http.h>
|
||||
#include "internal/sockets.h"
|
||||
#include "internal/cryptlib.h"
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
@@ -157,7 +157,7 @@ int OSSL_HTTP_REQ_CTX_header(OSSL_HTTP_REQ_CTX *rctx, const char *server,
|
||||
* Section 5.1.2 of RFC 1945 states that the absoluteURI form is only
|
||||
* allowed when using a proxy
|
||||
*/
|
||||
if (BIO_printf(rctx->mem, "http://%s", server) <= 0)
|
||||
if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0)
|
||||
return 0;
|
||||
if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0)
|
||||
return 0;
|
||||
@@ -330,7 +330,7 @@ static int parse_http_line1(char *line)
|
||||
for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
|
||||
continue;
|
||||
if (*code == '\0') {
|
||||
HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ static int parse_http_line1(char *line)
|
||||
code++;
|
||||
|
||||
if (*code == '\0') {
|
||||
HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ static int parse_http_line1(char *line)
|
||||
continue;
|
||||
|
||||
if (*reason == '\0') {
|
||||
HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -385,7 +385,7 @@ static int parse_http_line1(char *line)
|
||||
if (retcode < 400)
|
||||
HTTPerr(0, HTTP_R_STATUS_CODE_UNSUPPORTED);
|
||||
else
|
||||
HTTPerr(0, HTTP_R_SERVER_SENT_ERROR);
|
||||
HTTPerr(0, HTTP_R_RECEIVED_ERROR);
|
||||
if (*reason == '\0')
|
||||
ERR_add_error_data(2, "Code=", code);
|
||||
else
|
||||
@@ -577,12 +577,14 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
*line_end = '\0';
|
||||
}
|
||||
if (value != NULL && line_end != NULL) {
|
||||
if (rctx->state == OHS_REDIRECT && strcmp(key, "Location") == 0) {
|
||||
if (rctx->state == OHS_REDIRECT
|
||||
&& strcasecmp(key, "Location") == 0) {
|
||||
rctx->redirection_url = value;
|
||||
return 0;
|
||||
}
|
||||
if (rctx->expected_ct != NULL && strcmp(key, "Content-Type") == 0) {
|
||||
if (strcmp(rctx->expected_ct, value) != 0) {
|
||||
if (rctx->expected_ct != NULL
|
||||
&& strcasecmp(key, "Content-Type") == 0) {
|
||||
if (strcasecmp(rctx->expected_ct, value) != 0) {
|
||||
HTTPerr(0, HTTP_R_UNEXPECTED_CONTENT_TYPE);
|
||||
ERR_add_error_data(4, "expected=", rctx->expected_ct,
|
||||
",actual=", value);
|
||||
@@ -590,7 +592,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
}
|
||||
rctx->expected_ct = NULL; /* content-type has been found */
|
||||
}
|
||||
if (strcmp(key, "Content-Length") == 0) {
|
||||
if (strcasecmp(key, "Content-Length") == 0) {
|
||||
resp_len = strtoul(value, &line_end, 10);
|
||||
if (line_end == value || *line_end != '\0') {
|
||||
HTTPerr(0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH);
|
||||
@@ -603,7 +605,7 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
}
|
||||
|
||||
/* Look for blank line: end of headers */
|
||||
for (p = rctx->iobuf; *p != '\0' ; p++) {
|
||||
for (p = rctx->iobuf; *p != '\0'; p++) {
|
||||
if (*p != '\r' && *p != '\n')
|
||||
break;
|
||||
}
|
||||
@@ -690,23 +692,31 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
|
||||
/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */
|
||||
static BIO *HTTP_new_bio(const char *server, const char *server_port,
|
||||
const char *proxy, const char *proxy_port)
|
||||
static BIO *HTTP_new_bio(const char *server /* optionally includes ":port" */,
|
||||
const char *server_port /* explicit server port */,
|
||||
const char *proxy /* optionally includes ":port" */)
|
||||
{
|
||||
const char *host = server;
|
||||
const char *host = server, *host_end;
|
||||
char host_name[100];
|
||||
const char *port = server_port;
|
||||
BIO *cbio;
|
||||
|
||||
if (server == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
if (!ossl_assert(server != NULL))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (proxy != NULL) {
|
||||
host = proxy;
|
||||
port = proxy_port;
|
||||
port = NULL;
|
||||
}
|
||||
cbio = BIO_new_connect(host);
|
||||
|
||||
host_end = strchr(host, '/');
|
||||
if (host_end != NULL && (size_t)(host_end - host) < sizeof(host_name)) {
|
||||
/* chop trailing string starting with '/' */
|
||||
strncpy(host_name, host, host_end - host + 1);
|
||||
host = host_name;
|
||||
}
|
||||
|
||||
cbio = BIO_new_connect(host /* optionally includes ":port" */);
|
||||
if (cbio == NULL)
|
||||
goto end;
|
||||
if (port != NULL)
|
||||
@@ -724,7 +734,7 @@ static ASN1_VALUE *BIO_mem_d2i(BIO *mem, const ASN1_ITEM *it)
|
||||
ASN1_VALUE *resp = ASN1_item_d2i(NULL, &p, len, it);
|
||||
|
||||
if (resp == NULL)
|
||||
HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
return resp;
|
||||
}
|
||||
|
||||
@@ -812,7 +822,7 @@ static int update_timeout(int timeout, time_t start_time)
|
||||
* After disconnect the modified BIO will be deallocated using BIO_free_all().
|
||||
*/
|
||||
BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
int use_ssl, const char *proxy, const char *proxy_port,
|
||||
int use_ssl, const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
@@ -837,17 +847,28 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
HTTPerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
|
||||
return NULL;
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
if (bio != NULL)
|
||||
if (bio != NULL) {
|
||||
cbio = bio;
|
||||
else
|
||||
} else {
|
||||
#ifndef OPENSSL_NO_SOCK
|
||||
if ((cbio = HTTP_new_bio(server, port, proxy, proxy_port)) == NULL)
|
||||
if (server == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if (*port == '\0')
|
||||
port = NULL;
|
||||
if (port == NULL && strchr(server, ':') == NULL)
|
||||
port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
||||
proxy = http_adapt_proxy(proxy, no_proxy, server, use_ssl);
|
||||
if ((cbio = HTTP_new_bio(server, port, proxy)) == NULL)
|
||||
return NULL;
|
||||
#else
|
||||
HTTPerr(0, HTTP_R_SOCK_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
/* remaining parameters are checked indirectly by the functions called */
|
||||
|
||||
(void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
|
||||
if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0)
|
||||
@@ -889,15 +910,17 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT)
|
||||
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR)
|
||||
# ifndef OPENSSL_NO_CMP
|
||||
#ifndef OPENSSL_NO_CMP
|
||||
|| (lib == ERR_LIB_CMP
|
||||
&& reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
|
||||
# endif
|
||||
#endif
|
||||
) {
|
||||
BIO_snprintf(buf, 200, "server=%s:%s", server, port);
|
||||
ERR_add_error_data(1, buf);
|
||||
if (proxy != NULL)
|
||||
ERR_add_error_data(2, " proxy=", proxy);
|
||||
if (err == 0) {
|
||||
BIO_snprintf(buf, 200, "server has disconnected%s",
|
||||
BIO_snprintf(buf, 200, " peer has disconnected%s",
|
||||
use_ssl ? " violating the protocol" :
|
||||
", likely because it requires the use of TLS");
|
||||
ERR_add_error_data(1, buf);
|
||||
@@ -934,8 +957,7 @@ BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
|
||||
|
||||
static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
{
|
||||
static const char https[] = "https:";
|
||||
int https_len = 6; /* strlen(https) */
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME":");
|
||||
|
||||
if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
|
||||
HTTPerr(0, HTTP_R_TOO_MANY_REDIRECTIONS);
|
||||
@@ -943,8 +965,8 @@ static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
}
|
||||
if (*new_url == '/') /* redirection to same server => same protocol */
|
||||
return 1;
|
||||
if (strncmp(old_url, https, https_len) == 0 &&
|
||||
strncmp(new_url, https, https_len) != 0) {
|
||||
if (strncmp(old_url, OSSL_HTTPS_NAME":", https_len) == 0 &&
|
||||
strncmp(new_url, OSSL_HTTPS_NAME":", https_len) != 0) {
|
||||
HTTPerr(0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
|
||||
return 0;
|
||||
}
|
||||
@@ -952,7 +974,7 @@ static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
||||
}
|
||||
|
||||
/* Get data via HTTP from server at given URL, potentially with redirection */
|
||||
BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *proxy_port,
|
||||
BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
@@ -980,7 +1002,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *proxy_port,
|
||||
break;
|
||||
|
||||
new_rpath:
|
||||
resp = OSSL_HTTP_transfer(host, port, path, use_ssl, proxy, proxy_port,
|
||||
resp = OSSL_HTTP_transfer(host, port, path, use_ssl, proxy, no_proxy,
|
||||
bio, rbio,
|
||||
bio_update_fn, arg, headers, NULL, NULL,
|
||||
maxline, max_resp_len,
|
||||
@@ -1013,7 +1035,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *proxy_port,
|
||||
|
||||
/* Get ASN.1-encoded data via HTTP from server at given URL */
|
||||
ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url,
|
||||
const char *proxy, const char *proxy_port,
|
||||
const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
@@ -1028,7 +1050,7 @@ ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url,
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
if ((mem = OSSL_HTTP_get(url, proxy, proxy_port, bio, rbio, bio_update_fn,
|
||||
if ((mem = OSSL_HTTP_get(url, proxy, no_proxy, bio, rbio, bio_update_fn,
|
||||
arg, headers, maxline, max_resp_len, timeout,
|
||||
expected_content_type, 1 /* expect_asn1 */))
|
||||
!= NULL)
|
||||
@@ -1040,7 +1062,7 @@ ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url,
|
||||
/* Post ASN.1-encoded request via HTTP to server return ASN.1 response */
|
||||
ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port,
|
||||
const char *path, int use_ssl,
|
||||
const char *proxy, const char *proxy_port,
|
||||
const char *proxy, const char *no_proxy,
|
||||
BIO *bio, BIO *rbio,
|
||||
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
||||
const STACK_OF(CONF_VALUE) *headers,
|
||||
@@ -1061,7 +1083,7 @@ ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port,
|
||||
/* remaining parameters are checked indirectly */
|
||||
|
||||
req_mem = HTTP_asn1_item2bio(req_it, req);
|
||||
res_mem = OSSL_HTTP_transfer(server, port, path, use_ssl, proxy, proxy_port,
|
||||
res_mem = OSSL_HTTP_transfer(server, port, path, use_ssl, proxy, no_proxy,
|
||||
bio, rbio,
|
||||
bio_update_fn, arg, headers, content_type,
|
||||
req_mem /* may be NULL */, maxline,
|
||||
@@ -1107,8 +1129,8 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
const char *proxyuser, const char *proxypass,
|
||||
int timeout, BIO *bio_err, const char *prog)
|
||||
{
|
||||
# undef BUF_SIZE
|
||||
# define BUF_SIZE (8 * 1024)
|
||||
#undef BUF_SIZE
|
||||
#define BUF_SIZE (8 * 1024)
|
||||
char *mbuf = OPENSSL_malloc(BUF_SIZE);
|
||||
char *mbufp;
|
||||
int read_len = 0;
|
||||
@@ -1117,11 +1139,13 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
int rv;
|
||||
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
||||
|
||||
if (bio == NULL || server == NULL || port == NULL
|
||||
if (bio == NULL || server == NULL
|
||||
|| (bio_err != NULL && prog == NULL)) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
goto end;
|
||||
}
|
||||
if (port == NULL || *port == '\0')
|
||||
port = OSSL_HTTPS_PORT;
|
||||
|
||||
if (mbuf == NULL || fbio == NULL) {
|
||||
BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
|
||||
@@ -1193,7 +1217,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
|
||||
/* RFC 7231 4.3.6: any 2xx status code is valid */
|
||||
if (strncmp(mbuf, HTTP_PREFIX, strlen(HTTP_PREFIX)) != 0) {
|
||||
HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
|
||||
HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR);
|
||||
BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
|
||||
prog);
|
||||
/* Wrong protocol, not even HTTP, so stop reading headers */
|
||||
@@ -1201,7 +1225,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
}
|
||||
mbufp = mbuf + strlen(HTTP_PREFIX);
|
||||
if (strncmp(mbufp, HTTP_VERSION_PATT, strlen(HTTP_VERSION_PATT)) != 0) {
|
||||
HTTPerr(0, HTTP_R_SERVER_SENT_WRONG_HTTP_VERSION);
|
||||
HTTPerr(0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION);
|
||||
BIO_printf(bio_err,
|
||||
"%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
|
||||
prog, HTTP_VERSION_STR_LEN, mbufp);
|
||||
@@ -1241,6 +1265,5 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
}
|
||||
OPENSSL_free(mbuf);
|
||||
return ret;
|
||||
# undef BUF_SIZE
|
||||
#undef BUF_SIZE
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 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
|
||||
@@ -34,17 +34,19 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
|
||||
"missing content type"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_REDIRECT_LOCATION),
|
||||
"missing redirect location"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_ERROR), "received error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION),
|
||||
"received wrong http version"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP),
|
||||
"redirection from https to http"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_NOT_ENABLED),
|
||||
"redirection not enabled"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_LINE_TOO_LONG),
|
||||
"response line too long"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR),
|
||||
"server response parse error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_SENT_ERROR), "server sent error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_SENT_WRONG_HTTP_VERSION),
|
||||
"server sent wrong http version"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR),
|
||||
"response parse error"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED),
|
||||
"sock not supported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED),
|
||||
"status code unsupported"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled"},
|
||||
|
||||
+66
-5
@@ -11,6 +11,9 @@
|
||||
#include <openssl/httperr.h>
|
||||
#include <openssl/err.h>
|
||||
#include <string.h>
|
||||
#include "internal/cryptlib.h" /* for ossl_assert() */
|
||||
|
||||
#include "http_local.h"
|
||||
|
||||
/*
|
||||
* Parse a URL and split it up into host, port and path components and
|
||||
@@ -22,8 +25,11 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
{
|
||||
char *p, *buf;
|
||||
char *host;
|
||||
char *port = "80";
|
||||
const char *port = OSSL_HTTP_PORT;
|
||||
size_t https_len = strlen(OSSL_HTTPS_NAME);
|
||||
|
||||
if (!ossl_assert(https_len >= strlen(OSSL_HTTP_NAME)))
|
||||
return 0;
|
||||
if (url == NULL) {
|
||||
HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
@@ -44,16 +50,16 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
|
||||
/* Check for initial colon */
|
||||
p = strchr(buf, ':');
|
||||
if (p == NULL || p - buf > 5 /* strlen("https") */) {
|
||||
if (p == NULL || (size_t)(p - buf) > https_len) {
|
||||
p = buf;
|
||||
} else {
|
||||
*(p++) = '\0';
|
||||
|
||||
if (strcmp(buf, "https") == 0) {
|
||||
if (strcmp(buf, OSSL_HTTPS_NAME) == 0) {
|
||||
if (pssl != NULL)
|
||||
*pssl = 1;
|
||||
port = "443";
|
||||
} else if (strcmp(buf, "http") != 0) {
|
||||
port = OSSL_HTTPS_PORT;
|
||||
} else if (strcmp(buf, OSSL_HTTP_NAME) != 0) {
|
||||
goto parse_err;
|
||||
}
|
||||
|
||||
@@ -114,3 +120,58 @@ int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport,
|
||||
OPENSSL_free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_use_proxy(const char *no_proxy, const char *server)
|
||||
{
|
||||
size_t sl;
|
||||
const char *found = NULL;
|
||||
|
||||
if (!ossl_assert(server != NULL))
|
||||
return 0;
|
||||
sl = strlen(server);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv("no_proxy");
|
||||
if (no_proxy == NULL)
|
||||
no_proxy = getenv(OPENSSL_NO_PROXY);
|
||||
if (no_proxy != NULL)
|
||||
found = strstr(no_proxy, server);
|
||||
while (found != NULL
|
||||
&& ((found != no_proxy && found[-1] != ' ' && found[-1] != ',')
|
||||
|| (found[sl] != '\0' && found[sl] != ' ' && found[sl] != ',')))
|
||||
found = strstr(found + 1, server);
|
||||
return found == NULL;
|
||||
}
|
||||
|
||||
const char *http_adapt_proxy(const char *proxy, const char *no_proxy,
|
||||
const char *server, int use_ssl)
|
||||
{
|
||||
const int http_len = strlen(OSSL_HTTP_PREFIX);
|
||||
const int https_len = strlen(OSSL_HTTPS_PREFIX);
|
||||
|
||||
/*
|
||||
* using environment variable names, both lowercase and uppercase variants,
|
||||
* compatible with other HTTP client implementations like wget, curl and git
|
||||
*/
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? "https_proxy" : "http_proxy");
|
||||
if (proxy == NULL)
|
||||
proxy = getenv(use_ssl ? OPENSSL_HTTP_PROXY :
|
||||
OPENSSL_HTTPS_PROXY);
|
||||
if (proxy == NULL)
|
||||
return NULL;
|
||||
|
||||
/* skip any leading "http://" or "https://" */
|
||||
if (strncmp(proxy, OSSL_HTTP_PREFIX, http_len) == 0)
|
||||
proxy += http_len;
|
||||
else if (strncmp(proxy, OSSL_HTTPS_PREFIX, https_len) == 0)
|
||||
proxy += https_len;
|
||||
|
||||
if (*proxy == '\0' || !http_use_proxy(no_proxy, server))
|
||||
return NULL;
|
||||
return proxy;
|
||||
}
|
||||
@@ -45,5 +45,8 @@ ASN1_VALUE *HTTP_sendreq_bio(BIO *bio, OSSL_HTTP_bio_cb_t bio_update_fn,
|
||||
ASN1_VALUE *req, const ASN1_ITEM *req_it,
|
||||
int maxline, unsigned long max_resp_len,
|
||||
int timeout, const ASN1_ITEM *rsp_it);
|
||||
int http_use_proxy(const char *no_proxy, const char *server);
|
||||
const char *http_adapt_proxy(const char *proxy, const char *no_proxy,
|
||||
const char *server, int use_ssl);
|
||||
|
||||
#endif /* !defined OSSL_CRYPTO_HTTP_LOCAL_H */
|
||||
#endif /* !defined(OSSL_CRYPTO_HTTP_LOCAL_H) */
|
||||
@@ -1,3 +1,10 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
|
||||
$ALL=i_cbc.c i_cfb64.c i_ofb64.c i_ecb.c i_skey.c
|
||||
|
||||
SOURCE[../../libcrypto]=$ALL
|
||||
|
||||
# When all deprecated symbols are removed, libcrypto doesn't export the
|
||||
# idea functions, so we must include them directly in liblegacy.a
|
||||
IF[{- $disabled{'deprecated-3.0'} -}]
|
||||
SOURCE[../../providers/liblegacy.a]=$ALL
|
||||
ENDIF
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user