Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/evp/p_rsa_asn1.c
Line
Count
Source (jump to first uncovered line)
1
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2
 * project 2006.
3
 */
4
/* ====================================================================
5
 * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer. 
13
 *
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in
16
 *    the documentation and/or other materials provided with the
17
 *    distribution.
18
 *
19
 * 3. All advertising materials mentioning features or use of this
20
 *    software must display the following acknowledgment:
21
 *    "This product includes software developed by the OpenSSL Project
22
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23
 *
24
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25
 *    endorse or promote products derived from this software without
26
 *    prior written permission. For written permission, please contact
27
 *    licensing@OpenSSL.org.
28
 *
29
 * 5. Products derived from this software may not be called "OpenSSL"
30
 *    nor may "OpenSSL" appear in their names without prior written
31
 *    permission of the OpenSSL Project.
32
 *
33
 * 6. Redistributions of any form whatsoever must retain the following
34
 *    acknowledgment:
35
 *    "This product includes software developed by the OpenSSL Project
36
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37
 *
38
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49
 * OF THE POSSIBILITY OF SUCH DAMAGE.
50
 * ====================================================================
51
 *
52
 * This product includes cryptographic software written by Eric Young
53
 * (eay@cryptsoft.com).  This product includes software written by Tim
54
 * Hudson (tjh@cryptsoft.com). */
55
56
#include <openssl/evp.h>
57
58
#include <openssl/bn.h>
59
#include <openssl/bytestring.h>
60
#include <openssl/digest.h>
61
#include <openssl/err.h>
62
#include <openssl/mem.h>
63
#include <openssl/rsa.h>
64
65
#include "../fipsmodule/rsa/internal.h"
66
#include "internal.h"
67
68
69
0
static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) {
70
  // See RFC 3279, section 2.3.1.
71
0
  const RSA *rsa = key->pkey;
72
0
  CBB spki, algorithm, oid, null, key_bitstring;
73
0
  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
74
0
      !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
75
0
      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
76
0
      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
77
0
      !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
78
0
      !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
79
0
      !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
80
0
      !RSA_marshal_public_key(&key_bitstring, rsa) ||
81
0
      !CBB_flush(out)) {
82
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
83
0
    return 0;
84
0
  }
85
86
0
  return 1;
87
0
}
88
89
0
static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
90
  // See RFC 3279, section 2.3.1.
91
92
  // The parameters must be NULL.
93
0
  CBS null;
94
0
  if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
95
0
      CBS_len(&null) != 0 ||
96
0
      CBS_len(params) != 0) {
97
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
98
0
    return 0;
99
0
  }
100
101
0
  RSA *rsa = RSA_parse_public_key(key);
102
0
  if (rsa == NULL || CBS_len(key) != 0) {
103
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
104
0
    RSA_free(rsa);
105
0
    return 0;
106
0
  }
107
108
0
  EVP_PKEY_assign_RSA(out, rsa);
109
0
  return 1;
110
0
}
111
112
0
static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
113
0
  const RSA *a_rsa = a->pkey;
114
0
  const RSA *b_rsa = b->pkey;
115
0
  return BN_cmp(RSA_get0_n(b_rsa), RSA_get0_n(a_rsa)) == 0 &&
116
0
         BN_cmp(RSA_get0_e(b_rsa), RSA_get0_e(a_rsa)) == 0;
117
0
}
118
119
0
static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) {
120
0
  const RSA *rsa = key->pkey;
121
0
  CBB pkcs8, algorithm, oid, null, private_key;
122
0
  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
123
0
      !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
124
0
      !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
125
0
      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
126
0
      !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) ||
127
0
      !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) ||
128
0
      !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
129
0
      !RSA_marshal_private_key(&private_key, rsa) ||
130
0
      !CBB_flush(out)) {
131
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
132
0
    return 0;
133
0
  }
134
135
0
  return 1;
136
0
}
137
138
0
static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
139
  // Per RFC 3447, A.1, the parameters have type NULL.
140
0
  CBS null;
141
0
  if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) ||
142
0
      CBS_len(&null) != 0 ||
143
0
      CBS_len(params) != 0) {
144
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
145
0
    return 0;
146
0
  }
147
148
0
  RSA *rsa = RSA_parse_private_key(key);
149
0
  if (rsa == NULL || CBS_len(key) != 0) {
150
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
151
0
    RSA_free(rsa);
152
0
    return 0;
153
0
  }
154
155
0
  EVP_PKEY_assign_RSA(out, rsa);
156
0
  return 1;
157
0
}
158
159
0
static int rsa_opaque(const EVP_PKEY *pkey) {
160
0
  const RSA *rsa = pkey->pkey;
161
0
  return RSA_is_opaque(rsa);
162
0
}
163
164
0
static int int_rsa_size(const EVP_PKEY *pkey) {
165
0
  const RSA *rsa = pkey->pkey;
166
0
  return RSA_size(rsa);
167
0
}
168
169
0
static int rsa_bits(const EVP_PKEY *pkey) {
170
0
  const RSA *rsa = pkey->pkey;
171
0
  return RSA_bits(rsa);
172
0
}
173
174
0
static void int_rsa_free(EVP_PKEY *pkey) {
175
0
  RSA_free(pkey->pkey);
176
0
  pkey->pkey = NULL;
177
0
}
178
179
const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
180
    EVP_PKEY_RSA,
181
    // 1.2.840.113549.1.1.1
182
    {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01},
183
    9,
184
185
    &rsa_pkey_meth,
186
187
    rsa_pub_decode,
188
    rsa_pub_encode,
189
    rsa_pub_cmp,
190
191
    rsa_priv_decode,
192
    rsa_priv_encode,
193
194
    /*set_priv_raw=*/NULL,
195
    /*set_pub_raw=*/NULL,
196
    /*get_priv_raw=*/NULL,
197
    /*get_pub_raw=*/NULL,
198
    /*set1_tls_encodedpoint=*/NULL,
199
    /*get1_tls_encodedpoint=*/NULL,
200
201
    rsa_opaque,
202
203
    int_rsa_size,
204
    rsa_bits,
205
206
    0,
207
    0,
208
    0,
209
210
    int_rsa_free,
211
};
212
213
0
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) {
214
0
  if (EVP_PKEY_assign_RSA(pkey, key)) {
215
0
    RSA_up_ref(key);
216
0
    return 1;
217
0
  }
218
0
  return 0;
219
0
}
220
221
0
int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
222
0
  evp_pkey_set_method(pkey, &rsa_asn1_meth);
223
0
  pkey->pkey = key;
224
0
  return key != NULL;
225
0
}
226
227
0
RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) {
228
0
  if (pkey->type != EVP_PKEY_RSA) {
229
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
230
0
    return NULL;
231
0
  }
232
0
  return pkey->pkey;
233
0
}
234
235
0
RSA *EVP_PKEY_get1_RSA(const EVP_PKEY *pkey) {
236
0
  RSA *rsa = EVP_PKEY_get0_RSA(pkey);
237
0
  if (rsa != NULL) {
238
0
    RSA_up_ref(rsa);
239
0
  }
240
0
  return rsa;
241
0
}