Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 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 | |
Brian Smith | dc6c1b8 | 2016-01-17 22:21:42 -1000 | [diff] [blame] | 57 | #include <openssl/x509.h> |
| 58 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 59 | #include <limits.h> |
| 60 | |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 61 | #include <openssl/asn1.h> |
| 62 | #include <openssl/asn1t.h> |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 63 | #include <openssl/bytestring.h> |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 64 | #include <openssl/err.h> |
| 65 | #include <openssl/evp.h> |
| 66 | #include <openssl/mem.h> |
| 67 | #include <openssl/obj.h> |
Brian Smith | 054e682 | 2015-03-27 21:12:01 -1000 | [diff] [blame] | 68 | #include <openssl/thread.h> |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 69 | |
Adam Langley | 4bdb6e4 | 2015-05-15 15:29:21 -0700 | [diff] [blame] | 70 | #include "../internal.h" |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 71 | |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 72 | /* Minor tweak to operation: free up EVP_PKEY */ |
| 73 | static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 74 | void *exarg) |
| 75 | { |
| 76 | if (operation == ASN1_OP_FREE_POST) { |
| 77 | X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; |
| 78 | EVP_PKEY_free(pubkey->pkey); |
| 79 | } |
| 80 | return 1; |
| 81 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 82 | |
| 83 | ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 84 | ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), |
| 85 | ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 86 | } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) |
| 87 | |
| 88 | IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) |
| 89 | |
| 90 | int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 91 | { |
| 92 | X509_PUBKEY *pk = NULL; |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 93 | uint8_t *spki = NULL; |
| 94 | size_t spki_len; |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 95 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 96 | if (x == NULL) |
| 97 | return (0); |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 98 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 99 | CBB cbb; |
| 100 | if (!CBB_init(&cbb, 0) || |
| 101 | !EVP_marshal_public_key(&cbb, pkey) || |
| 102 | !CBB_finish(&cbb, &spki, &spki_len) || |
| 103 | spki_len > LONG_MAX) { |
| 104 | CBB_cleanup(&cbb); |
| 105 | OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 106 | goto error; |
| 107 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 108 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 109 | const uint8_t *p = spki; |
| 110 | pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); |
| 111 | if (pk == NULL || p != spki + spki_len) { |
| 112 | OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); |
| 113 | goto error; |
| 114 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 115 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 116 | OPENSSL_free(spki); |
| 117 | X509_PUBKEY_free(*x); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 118 | *x = pk; |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 119 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 120 | return 1; |
| 121 | error: |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 122 | X509_PUBKEY_free(pk); |
| 123 | OPENSSL_free(spki); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 124 | return 0; |
| 125 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 126 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 127 | /* g_pubkey_lock is used to protect the initialisation of the |pkey| member of |
| 128 | * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| |
| 129 | * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is |
| 130 | * not. */ |
Adam Langley | 4bdb6e4 | 2015-05-15 15:29:21 -0700 | [diff] [blame] | 131 | static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; |
| 132 | |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 133 | EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 134 | { |
| 135 | EVP_PKEY *ret = NULL; |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 136 | uint8_t *spki = NULL; |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 137 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 138 | if (key == NULL) |
| 139 | goto error; |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 140 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 141 | CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); |
| 142 | if (key->pkey != NULL) { |
David Benjamin | 29270de | 2016-05-24 15:28:36 +0000 | [diff] [blame] | 143 | CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); |
Adam Langley | 310d3f6 | 2016-07-12 10:39:20 -0700 | [diff] [blame] | 144 | EVP_PKEY_up_ref(key->pkey); |
| 145 | return key->pkey; |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 146 | } |
David Benjamin | 29270de | 2016-05-24 15:28:36 +0000 | [diff] [blame] | 147 | CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 148 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 149 | /* Re-encode the |X509_PUBKEY| to DER and parse it. */ |
| 150 | int spki_len = i2d_X509_PUBKEY(key, &spki); |
| 151 | if (spki_len < 0) { |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 152 | goto error; |
| 153 | } |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 154 | CBS cbs; |
| 155 | CBS_init(&cbs, spki, (size_t)spki_len); |
| 156 | ret = EVP_parse_public_key(&cbs); |
| 157 | if (ret == NULL || CBS_len(&cbs) != 0) { |
| 158 | OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 159 | goto error; |
| 160 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 161 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 162 | /* Check to see if another thread set key->pkey first */ |
| 163 | CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); |
| 164 | if (key->pkey) { |
David Benjamin | 29270de | 2016-05-24 15:28:36 +0000 | [diff] [blame] | 165 | CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 166 | EVP_PKEY_free(ret); |
| 167 | ret = key->pkey; |
| 168 | } else { |
| 169 | key->pkey = ret; |
David Benjamin | 29270de | 2016-05-24 15:28:36 +0000 | [diff] [blame] | 170 | CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 171 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 172 | |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 173 | OPENSSL_free(spki); |
Adam Langley | 310d3f6 | 2016-07-12 10:39:20 -0700 | [diff] [blame] | 174 | EVP_PKEY_up_ref(ret); |
| 175 | return ret; |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 176 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 177 | error: |
David Benjamin | 68772b3 | 2015-12-30 21:40:40 -0500 | [diff] [blame] | 178 | OPENSSL_free(spki); |
| 179 | EVP_PKEY_free(ret); |
| 180 | return NULL; |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 181 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 182 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 183 | /* |
| 184 | * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or |
| 185 | * decode as X509_PUBKEY |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 186 | */ |
| 187 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 188 | EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) |
| 189 | { |
| 190 | X509_PUBKEY *xpk; |
| 191 | EVP_PKEY *pktmp; |
| 192 | xpk = d2i_X509_PUBKEY(NULL, pp, length); |
| 193 | if (!xpk) |
| 194 | return NULL; |
| 195 | pktmp = X509_PUBKEY_get(xpk); |
| 196 | X509_PUBKEY_free(xpk); |
| 197 | if (!pktmp) |
| 198 | return NULL; |
| 199 | if (a) { |
| 200 | EVP_PKEY_free(*a); |
| 201 | *a = pktmp; |
| 202 | } |
| 203 | return pktmp; |
| 204 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 205 | |
| 206 | int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 207 | { |
| 208 | X509_PUBKEY *xpk = NULL; |
| 209 | int ret; |
| 210 | if (!a) |
| 211 | return 0; |
| 212 | if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)a)) |
| 213 | return 0; |
| 214 | ret = i2d_X509_PUBKEY(xpk, pp); |
| 215 | X509_PUBKEY_free(xpk); |
| 216 | return ret; |
| 217 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 218 | |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 219 | /* |
| 220 | * The following are equivalents but which return RSA and DSA keys |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 221 | */ |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 222 | RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) |
| 223 | { |
| 224 | EVP_PKEY *pkey; |
| 225 | RSA *key; |
| 226 | const unsigned char *q; |
| 227 | q = *pp; |
| 228 | pkey = d2i_PUBKEY(NULL, &q, length); |
| 229 | if (!pkey) |
| 230 | return NULL; |
| 231 | key = EVP_PKEY_get1_RSA(pkey); |
| 232 | EVP_PKEY_free(pkey); |
| 233 | if (!key) |
| 234 | return NULL; |
| 235 | *pp = q; |
| 236 | if (a) { |
| 237 | RSA_free(*a); |
| 238 | *a = key; |
| 239 | } |
| 240 | return key; |
| 241 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 242 | |
| 243 | int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 244 | { |
| 245 | EVP_PKEY *pktmp; |
| 246 | int ret; |
| 247 | if (!a) |
| 248 | return 0; |
| 249 | pktmp = EVP_PKEY_new(); |
| 250 | if (!pktmp) { |
| 251 | OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); |
| 252 | return 0; |
| 253 | } |
| 254 | EVP_PKEY_set1_RSA(pktmp, (RSA *)a); |
| 255 | ret = i2d_PUBKEY(pktmp, pp); |
| 256 | EVP_PKEY_free(pktmp); |
| 257 | return ret; |
| 258 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 259 | |
| 260 | #ifndef OPENSSL_NO_DSA |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 261 | DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) |
| 262 | { |
| 263 | EVP_PKEY *pkey; |
| 264 | DSA *key; |
| 265 | const unsigned char *q; |
| 266 | q = *pp; |
| 267 | pkey = d2i_PUBKEY(NULL, &q, length); |
| 268 | if (!pkey) |
| 269 | return NULL; |
| 270 | key = EVP_PKEY_get1_DSA(pkey); |
| 271 | EVP_PKEY_free(pkey); |
| 272 | if (!key) |
| 273 | return NULL; |
| 274 | *pp = q; |
| 275 | if (a) { |
| 276 | DSA_free(*a); |
| 277 | *a = key; |
| 278 | } |
| 279 | return key; |
| 280 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 281 | |
| 282 | int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 283 | { |
| 284 | EVP_PKEY *pktmp; |
| 285 | int ret; |
| 286 | if (!a) |
| 287 | return 0; |
| 288 | pktmp = EVP_PKEY_new(); |
| 289 | if (!pktmp) { |
| 290 | OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); |
| 291 | return 0; |
| 292 | } |
| 293 | EVP_PKEY_set1_DSA(pktmp, (DSA *)a); |
| 294 | ret = i2d_PUBKEY(pktmp, pp); |
| 295 | EVP_PKEY_free(pktmp); |
| 296 | return ret; |
| 297 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 298 | #endif |
| 299 | |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 300 | EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 301 | { |
| 302 | EVP_PKEY *pkey; |
| 303 | EC_KEY *key; |
| 304 | const unsigned char *q; |
| 305 | q = *pp; |
| 306 | pkey = d2i_PUBKEY(NULL, &q, length); |
| 307 | if (!pkey) |
| 308 | return (NULL); |
| 309 | key = EVP_PKEY_get1_EC_KEY(pkey); |
| 310 | EVP_PKEY_free(pkey); |
| 311 | if (!key) |
| 312 | return (NULL); |
| 313 | *pp = q; |
| 314 | if (a) { |
| 315 | EC_KEY_free(*a); |
| 316 | *a = key; |
| 317 | } |
| 318 | return (key); |
| 319 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 320 | |
| 321 | int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp) |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 322 | { |
| 323 | EVP_PKEY *pktmp; |
| 324 | int ret; |
| 325 | if (!a) |
| 326 | return (0); |
| 327 | if ((pktmp = EVP_PKEY_new()) == NULL) { |
| 328 | OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); |
| 329 | return (0); |
| 330 | } |
| 331 | EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a); |
| 332 | ret = i2d_PUBKEY(pktmp, pp); |
| 333 | EVP_PKEY_free(pktmp); |
| 334 | return (ret); |
| 335 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 336 | |
| 337 | int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj, |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 338 | int ptype, void *pval, |
| 339 | unsigned char *penc, int penclen) |
| 340 | { |
| 341 | if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) |
| 342 | return 0; |
| 343 | if (penc) { |
| 344 | if (pub->public_key->data) |
| 345 | OPENSSL_free(pub->public_key->data); |
| 346 | pub->public_key->data = penc; |
| 347 | pub->public_key->length = penclen; |
| 348 | /* Set number of unused bits to zero */ |
| 349 | pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); |
| 350 | pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; |
| 351 | } |
| 352 | return 1; |
| 353 | } |
Adam Langley | 95c29f3 | 2014-06-20 12:00:00 -0700 | [diff] [blame] | 354 | |
| 355 | int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, |
Adam Langley | 57707c7 | 2016-01-14 11:25:12 -0800 | [diff] [blame] | 356 | const unsigned char **pk, int *ppklen, |
| 357 | X509_ALGOR **pa, X509_PUBKEY *pub) |
| 358 | { |
| 359 | if (ppkalg) |
| 360 | *ppkalg = pub->algor->algorithm; |
| 361 | if (pk) { |
| 362 | *pk = pub->public_key->data; |
| 363 | *ppklen = pub->public_key->length; |
| 364 | } |
| 365 | if (pa) |
| 366 | *pa = pub->algor; |
| 367 | return 1; |
| 368 | } |