x_pubkey.c
Go to the documentation of this file.
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to. The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  * notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  * must display the following acknowledgement:
32  * "This product includes cryptographic software written by
33  * Eric Young (eay@cryptsoft.com)"
34  * The word 'cryptographic' can be left out if the rouines from the library
35  * being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  * the apps directory (application code) you must include an acknowledgement:
38  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed. i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/x509.h>
58 
59 #include <limits.h>
60 
61 #include <openssl/asn1.h>
62 #include <openssl/asn1t.h>
63 #include <openssl/bytestring.h>
64 #include <openssl/err.h>
65 #include <openssl/evp.h>
66 #include <openssl/mem.h>
67 #include <openssl/obj.h>
68 #include <openssl/thread.h>
69 
70 #include "../internal.h"
71 #include "internal.h"
72 
73 /* Minor tweak to operation: free up EVP_PKEY */
74 static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
75  void *exarg)
76 {
77  if (operation == ASN1_OP_FREE_POST) {
78  X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
79  EVP_PKEY_free(pubkey->pkey);
80  }
81  return 1;
82 }
83 
88 
90 
92 {
93  X509_PUBKEY *pk = NULL;
94  uint8_t *spki = NULL;
95  size_t spki_len;
96 
97  if (x == NULL)
98  return (0);
99 
100  CBB cbb;
101  if (!CBB_init(&cbb, 0) ||
102  !EVP_marshal_public_key(&cbb, pkey) ||
103  !CBB_finish(&cbb, &spki, &spki_len) ||
104  spki_len > LONG_MAX) {
105  CBB_cleanup(&cbb);
107  goto error;
108  }
109 
110  const uint8_t *p = spki;
111  pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len);
112  if (pk == NULL || p != spki + spki_len) {
114  goto error;
115  }
116 
117  OPENSSL_free(spki);
119  *x = pk;
120 
121  return 1;
122  error:
123  X509_PUBKEY_free(pk);
124  OPENSSL_free(spki);
125  return 0;
126 }
127 
128 /* g_pubkey_lock is used to protect the initialisation of the |pkey| member of
129  * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t|
130  * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is
131  * not. */
132 static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT;
133 
135 {
136  EVP_PKEY *ret = NULL;
137  uint8_t *spki = NULL;
138 
139  if (key == NULL)
140  goto error;
141 
142  CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock);
143  if (key->pkey != NULL) {
144  CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock);
145  EVP_PKEY_up_ref(key->pkey);
146  return key->pkey;
147  }
148  CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock);
149 
150  /* Re-encode the |X509_PUBKEY| to DER and parse it. */
151  int spki_len = i2d_X509_PUBKEY(key, &spki);
152  if (spki_len < 0) {
153  goto error;
154  }
155  CBS cbs;
156  CBS_init(&cbs, spki, (size_t)spki_len);
158  if (ret == NULL || CBS_len(&cbs) != 0) {
160  goto error;
161  }
162 
163  /* Check to see if another thread set key->pkey first */
164  CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
165  if (key->pkey) {
166  CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock);
168  ret = key->pkey;
169  } else {
170  key->pkey = ret;
171  CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock);
172  }
173 
174  OPENSSL_free(spki);
176  return ret;
177 
178  error:
179  OPENSSL_free(spki);
181  return NULL;
182 }
183 
185  void *param_value, uint8_t *key, int key_len)
186 {
187  if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) {
188  return 0;
189  }
190 
191  ASN1_STRING_set0(pub->public_key, key, key_len);
192  /* Set the number of unused bits to zero. */
193  pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
195  return 1;
196 }
197 
198 int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key,
199  int *out_key_len, X509_ALGOR **out_alg,
200  X509_PUBKEY *pub)
201 {
202  if (out_obj != NULL) {
203  *out_obj = pub->algor->algorithm;
204  }
205  if (out_key != NULL) {
206  *out_key = pub->public_key->data;
207  *out_key_len = pub->public_key->length;
208  }
209  if (out_alg != NULL) {
210  *out_alg = pub->algor;
211  }
212  return 1;
213 }
214 
216  return pub->public_key;
217 }
X509_pubkey_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:82
obj
OPENSSL_EXPORT const ASN1_OBJECT * obj
Definition: x509.h:1671
CRYPTO_STATIC_MUTEX_INIT
#define CRYPTO_STATIC_MUTEX_INIT
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:536
public_key
Definition: hrss.c:1881
CBB_init
#define CBB_init
Definition: boringssl_prefix_symbols.h:1047
regen-readme.it
it
Definition: regen-readme.py:15
cbs_st
Definition: bytestring.h:39
CBB_cleanup
#define CBB_cleanup
Definition: boringssl_prefix_symbols.h:1039
X509_algor_st::algorithm
ASN1_OBJECT * algorithm
Definition: x509.h:114
evp.h
EVP_marshal_public_key
#define EVP_marshal_public_key
Definition: boringssl_prefix_symbols.h:1737
CRYPTO_STATIC_MUTEX_unlock_write
#define CRYPTO_STATIC_MUTEX_unlock_write
Definition: boringssl_prefix_symbols.h:1135
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
internal.h
X509_ALGOR_set0
OPENSSL_EXPORT int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *obj, int param_type, void *param_value)
X509_R_PUBLIC_KEY_ENCODE_ERROR
#define X509_R_PUBLIC_KEY_ENCODE_ERROR
Definition: x509.h:2403
X509_PUBKEY_get0_public_key
const ASN1_BIT_STRING * X509_PUBKEY_get0_public_key(const X509_PUBKEY *pub)
Definition: x_pubkey.c:215
error
grpc_error_handle error
Definition: retry_filter.cc:499
CBS_len
#define CBS_len
Definition: boringssl_prefix_symbols.h:1089
d2i_X509_PUBKEY
#define d2i_X509_PUBKEY
Definition: boringssl_prefix_symbols.h:3046
X509_PUBKEY_get
EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key)
Definition: x_pubkey.c:134
cbs
const CBS * cbs
Definition: third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h:107
xds_manager.p
p
Definition: xds_manager.py:60
CBS_init
#define CBS_init
Definition: boringssl_prefix_symbols.h:1085
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
ASN1_SEQUENCE_cb
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb)
IMPLEMENT_ASN1_FUNCTIONS
#define IMPLEMENT_ASN1_FUNCTIONS(stname)
Definition: asn1t.h:636
asn1_string_st::data
unsigned char * data
Definition: asn1.h:546
X509_pubkey_st::pkey
EVP_PKEY * pkey
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:85
asn1_object_st
Definition: third_party/boringssl-with-bazel/src/crypto/asn1/internal.h:102
CRYPTO_STATIC_MUTEX
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:533
asn1_string_st::flags
long flags
Definition: asn1.h:547
bytestring.h
ASN1_ITEM_st
Definition: asn1t.h:459
i2d_X509_PUBKEY
#define i2d_X509_PUBKEY
Definition: boringssl_prefix_symbols.h:3290
evp_pkey_st
Definition: evp.h:1046
asn1_string_st::length
int length
Definition: asn1.h:544
CBB_finish
#define CBB_finish
Definition: boringssl_prefix_symbols.h:1043
CRYPTO_STATIC_MUTEX_unlock_read
#define CRYPTO_STATIC_MUTEX_unlock_read
Definition: boringssl_prefix_symbols.h:1134
CRYPTO_STATIC_MUTEX_lock_write
#define CRYPTO_STATIC_MUTEX_lock_write
Definition: boringssl_prefix_symbols.h:1133
EVP_PKEY_free
#define EVP_PKEY_free
Definition: boringssl_prefix_symbols.h:1625
X509_R_PUBLIC_KEY_DECODE_ERROR
#define X509_R_PUBLIC_KEY_DECODE_ERROR
Definition: x509.h:2402
err.h
asn1t.h
ASN1_STRING_FLAG_BITS_LEFT
#define ASN1_STRING_FLAG_BITS_LEFT
Definition: asn1.h:554
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
X509_algor_st
Definition: x509.h:113
key
const char * key
Definition: hpack_parser_table.cc:164
x509_st
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:139
EVP_PKEY_up_ref
#define EVP_PKEY_up_ref
Definition: boringssl_prefix_symbols.h:1660
X509_pubkey_st::algor
X509_ALGOR * algor
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:83
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
EVP_parse_public_key
#define EVP_parse_public_key
Definition: boringssl_prefix_symbols.h:1743
X509_pubkey_st::public_key
ASN1_BIT_STRING * public_key
Definition: third_party/boringssl-with-bazel/src/crypto/x509/internal.h:84
ASN1_VALUE
struct ASN1_VALUE_st ASN1_VALUE
Definition: asn1.h:320
pubkey_cb
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
Definition: x_pubkey.c:74
X509_PUBKEY_set0_param
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, int param_type, void *param_value, uint8_t *key, int key_len)
Definition: x_pubkey.c:184
obj.h
X509_PUBKEY_set
OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
CRYPTO_STATIC_MUTEX_lock_read
#define CRYPTO_STATIC_MUTEX_lock_read
Definition: boringssl_prefix_symbols.h:1132
ASN1_STRING_set0
#define ASN1_STRING_set0
Definition: boringssl_prefix_symbols.h:689
mem.h
ASN1_OP_FREE_POST
#define ASN1_OP_FREE_POST
Definition: asn1t.h:598
ASN1_SEQUENCE_END_cb
#define ASN1_SEQUENCE_END_cb(stname, tname)
Definition: asn1t.h:161
thread.h
OPENSSL_free
#define OPENSSL_free
Definition: boringssl_prefix_symbols.h:1869
X509_PUBKEY_get0_param
int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key, int *out_key_len, X509_ALGOR **out_alg, X509_PUBKEY *pub)
Definition: x_pubkey.c:198
X509_PUBKEY_free
#define X509_PUBKEY_free
Definition: boringssl_prefix_symbols.h:2407
asn1_string_st
Definition: asn1.h:543
asn1.h
x509.h
cbb_st
Definition: bytestring.h:375
ASN1_SIMPLE
#define ASN1_SIMPLE(stname, field, type)
Definition: asn1t.h:265


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:56