1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include <stdlib.h>
12e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
13e1051a39Sopenharmony_ci#include <openssl/objects.h>
14e1051a39Sopenharmony_ci#include <openssl/evp.h>
15e1051a39Sopenharmony_ci#include "crypto/bn.h"
16e1051a39Sopenharmony_ci#ifndef FIPS_MODULE
17e1051a39Sopenharmony_ci# include "crypto/asn1.h"
18e1051a39Sopenharmony_ci#endif
19e1051a39Sopenharmony_ci#include "crypto/evp.h"
20e1051a39Sopenharmony_ci#include "evp_local.h"
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_ci/*
23e1051a39Sopenharmony_ci * Returns:
24e1051a39Sopenharmony_ci *  1   True
25e1051a39Sopenharmony_ci *  0   False
26e1051a39Sopenharmony_ci * -1   Unsupported (use legacy path)
27e1051a39Sopenharmony_ci */
28e1051a39Sopenharmony_cistatic int try_provided_check(EVP_PKEY_CTX *ctx, int selection, int checktype)
29e1051a39Sopenharmony_ci{
30e1051a39Sopenharmony_ci    EVP_KEYMGMT *keymgmt;
31e1051a39Sopenharmony_ci    void *keydata;
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ci    if (evp_pkey_ctx_is_legacy(ctx))
34e1051a39Sopenharmony_ci        return -1;
35e1051a39Sopenharmony_ci
36e1051a39Sopenharmony_ci    keymgmt = ctx->keymgmt;
37e1051a39Sopenharmony_ci    keydata = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
38e1051a39Sopenharmony_ci                                          &keymgmt, ctx->propquery);
39e1051a39Sopenharmony_ci    if (keydata == NULL) {
40e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
41e1051a39Sopenharmony_ci        return 0;
42e1051a39Sopenharmony_ci    }
43e1051a39Sopenharmony_ci
44e1051a39Sopenharmony_ci    return evp_keymgmt_validate(keymgmt, keydata, selection, checktype);
45e1051a39Sopenharmony_ci}
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_cistatic int evp_pkey_public_check_combined(EVP_PKEY_CTX *ctx, int checktype)
48e1051a39Sopenharmony_ci{
49e1051a39Sopenharmony_ci    EVP_PKEY *pkey = ctx->pkey;
50e1051a39Sopenharmony_ci    int ok;
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ci    if (pkey == NULL) {
53e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
54e1051a39Sopenharmony_ci        return 0;
55e1051a39Sopenharmony_ci    }
56e1051a39Sopenharmony_ci
57e1051a39Sopenharmony_ci    if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
58e1051a39Sopenharmony_ci                                 checktype)) != -1)
59e1051a39Sopenharmony_ci        return ok;
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci    if (pkey->type == EVP_PKEY_NONE)
62e1051a39Sopenharmony_ci        goto not_supported;
63e1051a39Sopenharmony_ci
64e1051a39Sopenharmony_ci#ifndef FIPS_MODULE
65e1051a39Sopenharmony_ci    /* legacy */
66e1051a39Sopenharmony_ci    /* call customized public key check function first */
67e1051a39Sopenharmony_ci    if (ctx->pmeth->public_check != NULL)
68e1051a39Sopenharmony_ci        return ctx->pmeth->public_check(pkey);
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    /* use default public key check function in ameth */
71e1051a39Sopenharmony_ci    if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL)
72e1051a39Sopenharmony_ci        goto not_supported;
73e1051a39Sopenharmony_ci
74e1051a39Sopenharmony_ci    return pkey->ameth->pkey_public_check(pkey);
75e1051a39Sopenharmony_ci#endif
76e1051a39Sopenharmony_ci not_supported:
77e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
78e1051a39Sopenharmony_ci    return -2;
79e1051a39Sopenharmony_ci}
80e1051a39Sopenharmony_ci
81e1051a39Sopenharmony_ciint EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
82e1051a39Sopenharmony_ci{
83e1051a39Sopenharmony_ci    return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK);
84e1051a39Sopenharmony_ci}
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ciint EVP_PKEY_public_check_quick(EVP_PKEY_CTX *ctx)
87e1051a39Sopenharmony_ci{
88e1051a39Sopenharmony_ci    return evp_pkey_public_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK);
89e1051a39Sopenharmony_ci}
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_cistatic int evp_pkey_param_check_combined(EVP_PKEY_CTX *ctx, int checktype)
92e1051a39Sopenharmony_ci{
93e1051a39Sopenharmony_ci    EVP_PKEY *pkey = ctx->pkey;
94e1051a39Sopenharmony_ci    int ok;
95e1051a39Sopenharmony_ci
96e1051a39Sopenharmony_ci    if (pkey == NULL) {
97e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
98e1051a39Sopenharmony_ci        return 0;
99e1051a39Sopenharmony_ci    }
100e1051a39Sopenharmony_ci
101e1051a39Sopenharmony_ci    if ((ok = try_provided_check(ctx,
102e1051a39Sopenharmony_ci                                 OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
103e1051a39Sopenharmony_ci                                 checktype)) != -1)
104e1051a39Sopenharmony_ci        return ok;
105e1051a39Sopenharmony_ci
106e1051a39Sopenharmony_ci    if (pkey->type == EVP_PKEY_NONE)
107e1051a39Sopenharmony_ci        goto not_supported;
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_ci#ifndef FIPS_MODULE
110e1051a39Sopenharmony_ci    /* legacy */
111e1051a39Sopenharmony_ci    /* call customized param check function first */
112e1051a39Sopenharmony_ci    if (ctx->pmeth->param_check != NULL)
113e1051a39Sopenharmony_ci        return ctx->pmeth->param_check(pkey);
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ci    /* use default param check function in ameth */
116e1051a39Sopenharmony_ci    if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL)
117e1051a39Sopenharmony_ci        goto not_supported;
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    return pkey->ameth->pkey_param_check(pkey);
120e1051a39Sopenharmony_ci#endif
121e1051a39Sopenharmony_ci not_supported:
122e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
123e1051a39Sopenharmony_ci    return -2;
124e1051a39Sopenharmony_ci}
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_ciint EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
127e1051a39Sopenharmony_ci{
128e1051a39Sopenharmony_ci    return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK);
129e1051a39Sopenharmony_ci}
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ciint EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx)
132e1051a39Sopenharmony_ci{
133e1051a39Sopenharmony_ci    return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK);
134e1051a39Sopenharmony_ci}
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ciint EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
137e1051a39Sopenharmony_ci{
138e1051a39Sopenharmony_ci    EVP_PKEY *pkey = ctx->pkey;
139e1051a39Sopenharmony_ci    int ok;
140e1051a39Sopenharmony_ci
141e1051a39Sopenharmony_ci    if (pkey == NULL) {
142e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
143e1051a39Sopenharmony_ci        return 0;
144e1051a39Sopenharmony_ci    }
145e1051a39Sopenharmony_ci
146e1051a39Sopenharmony_ci    if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
147e1051a39Sopenharmony_ci                                 OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
148e1051a39Sopenharmony_ci        return ok;
149e1051a39Sopenharmony_ci
150e1051a39Sopenharmony_ci    /* not supported for legacy keys */
151e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
152e1051a39Sopenharmony_ci    return -2;
153e1051a39Sopenharmony_ci}
154e1051a39Sopenharmony_ci
155e1051a39Sopenharmony_ciint EVP_PKEY_check(EVP_PKEY_CTX *ctx)
156e1051a39Sopenharmony_ci{
157e1051a39Sopenharmony_ci    return EVP_PKEY_pairwise_check(ctx);
158e1051a39Sopenharmony_ci}
159e1051a39Sopenharmony_ci
160e1051a39Sopenharmony_ciint EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
161e1051a39Sopenharmony_ci{
162e1051a39Sopenharmony_ci    EVP_PKEY *pkey = ctx->pkey;
163e1051a39Sopenharmony_ci    int ok;
164e1051a39Sopenharmony_ci
165e1051a39Sopenharmony_ci    if (pkey == NULL) {
166e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET);
167e1051a39Sopenharmony_ci        return 0;
168e1051a39Sopenharmony_ci    }
169e1051a39Sopenharmony_ci
170e1051a39Sopenharmony_ci    if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR,
171e1051a39Sopenharmony_ci                                 OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
172e1051a39Sopenharmony_ci        return ok;
173e1051a39Sopenharmony_ci
174e1051a39Sopenharmony_ci    if (pkey->type == EVP_PKEY_NONE)
175e1051a39Sopenharmony_ci        goto not_supported;
176e1051a39Sopenharmony_ci
177e1051a39Sopenharmony_ci#ifndef FIPS_MODULE
178e1051a39Sopenharmony_ci    /* legacy */
179e1051a39Sopenharmony_ci    /* call customized check function first */
180e1051a39Sopenharmony_ci    if (ctx->pmeth->check != NULL)
181e1051a39Sopenharmony_ci        return ctx->pmeth->check(pkey);
182e1051a39Sopenharmony_ci
183e1051a39Sopenharmony_ci    /* use default check function in ameth */
184e1051a39Sopenharmony_ci    if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL)
185e1051a39Sopenharmony_ci        goto not_supported;
186e1051a39Sopenharmony_ci
187e1051a39Sopenharmony_ci    return pkey->ameth->pkey_check(pkey);
188e1051a39Sopenharmony_ci#endif
189e1051a39Sopenharmony_ci not_supported:
190e1051a39Sopenharmony_ci    ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
191e1051a39Sopenharmony_ci    return -2;
192e1051a39Sopenharmony_ci}
193e1051a39Sopenharmony_ci
194