Add RSA key validation to default provider
[openssl.git] / crypto / evp / pmeth_check.c
1 /*
2  * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/objects.h>
14 #include <openssl/evp.h>
15 #include "crypto/bn.h"
16 #include "crypto/asn1.h"
17 #include "crypto/evp.h"
18 #include "evp_local.h"
19
20 int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
21 {
22     EVP_PKEY *pkey = ctx->pkey;
23     void *key;
24     EVP_KEYMGMT *keymgmt;
25
26     if (pkey == NULL) {
27         EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET);
28         return 0;
29     }
30
31     keymgmt = pkey->pkeys[0].keymgmt;
32     key = pkey->pkeys[0].provdata;
33
34     if (key != NULL && keymgmt != NULL)
35         return evp_keymgmt_validate_public(keymgmt, key);
36
37     /* legacy */
38     /* call customized public key check function first */
39     if (ctx->pmeth->public_check != NULL)
40         return ctx->pmeth->public_check(pkey);
41
42     /* use default public key check function in ameth */
43     if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
44         EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
45                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
46         return -2;
47     }
48
49     return pkey->ameth->pkey_public_check(pkey);
50 }
51
52 int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
53 {
54     EVP_PKEY *pkey = ctx->pkey;
55     void *key;
56     EVP_KEYMGMT *keymgmt;
57
58     if (pkey == NULL) {
59         EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET);
60         return 0;
61     }
62
63     keymgmt = pkey->pkeys[0].keymgmt;
64     key = pkey->pkeys[0].provdata;
65
66     if (key != NULL && keymgmt != NULL)
67         return evp_keymgmt_validate_domparams(keymgmt, key);
68
69     /* call customized param check function first */
70     if (ctx->pmeth->param_check != NULL)
71         return ctx->pmeth->param_check(pkey);
72
73     /* legacy */
74     /* use default param check function in ameth */
75     if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
76         EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
77                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
78         return -2;
79     }
80
81     return pkey->ameth->pkey_param_check(pkey);
82 }
83
84 int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
85 {
86     EVP_PKEY *pkey = ctx->pkey;
87     void *key;
88     EVP_KEYMGMT *keymgmt;
89
90     if (pkey == NULL) {
91         EVPerr(0, EVP_R_NO_KEY_SET);
92         return 0;
93     }
94
95     keymgmt = pkey->pkeys[0].keymgmt;
96     key = pkey->pkeys[0].provdata;
97
98     if (key != NULL && keymgmt != NULL)
99         return evp_keymgmt_validate_private(keymgmt, key);
100     /* not supported for legacy keys */
101     return -2;
102 }
103
104 int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
105 {
106     EVP_PKEY *pkey = ctx->pkey;
107     void *key;
108     EVP_KEYMGMT *keymgmt;
109
110     if (pkey == NULL) {
111         EVPerr(0, EVP_R_NO_KEY_SET);
112         return 0;
113     }
114
115     keymgmt = pkey->pkeys[0].keymgmt;
116     key = pkey->pkeys[0].provdata;
117
118     if (key != NULL && keymgmt != NULL)
119         return evp_keymgmt_validate_pairwise(keymgmt, key);
120     /* not supported for legacy keys */
121     return -2;
122 }
123
124 int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
125 {
126     EVP_PKEY *pkey = ctx->pkey;
127     void *key;
128     EVP_KEYMGMT *keymgmt;
129
130     if (pkey == NULL) {
131         EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET);
132         return 0;
133     }
134
135     keymgmt = pkey->pkeys[0].keymgmt;
136     key = pkey->pkeys[0].provdata;
137
138     if (key != NULL && keymgmt != NULL) {
139         return evp_keymgmt_validate_domparams(keymgmt, key)
140                && evp_keymgmt_validate_public(keymgmt, key)
141                && evp_keymgmt_validate_private(keymgmt, key)
142                && evp_keymgmt_validate_pairwise(keymgmt, key);
143     }
144     /* legacy */
145     /* call customized check function first */
146     if (ctx->pmeth->check != NULL)
147         return ctx->pmeth->check(pkey);
148
149     /* use default check function in ameth */
150     if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
151         EVPerr(EVP_F_EVP_PKEY_CHECK,
152                EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
153         return -2;
154     }
155
156     return pkey->ameth->pkey_check(pkey);
157 }
158