p_lib.c 11.2 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10
 */

#include <stdio.h>
11
#include "internal/cryptlib.h"
B
Bodo Möller 已提交
12 13
#include <openssl/bn.h>
#include <openssl/err.h>
14 15 16
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
R
Rich Salz 已提交
17 18 19 20
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
#include <openssl/engine.h>
21

22
#include "internal/asn1_int.h"
D
Dr. Stephen Henson 已提交
23
#include "internal/evp_int.h"
24

25
static void EVP_PKEY_free_it(EVP_PKEY *x);
26

27
int EVP_PKEY_bits(const EVP_PKEY *pkey)
28 29 30 31 32
{
    if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
        return pkey->ameth->pkey_bits(pkey);
    return 0;
}
33

34
int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
35 36 37 38 39 40 41
{
    if (pkey == NULL)
        return 0;
    if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
        return -2;
    return pkey->ameth->pkey_security_bits(pkey);
}
42

U
Ulf Möller 已提交
43
int EVP_PKEY_size(EVP_PKEY *pkey)
44 45 46 47 48
{
    if (pkey && pkey->ameth && pkey->ameth->pkey_size)
        return pkey->ameth->pkey_size(pkey);
    return 0;
}
49

U
Ulf Möller 已提交
50
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
51
{
52
#ifndef OPENSSL_NO_DSA
53 54 55 56 57 58 59
    if (pkey->type == EVP_PKEY_DSA) {
        int ret = pkey->save_parameters;

        if (mode >= 0)
            pkey->save_parameters = mode;
        return (ret);
    }
B
Bodo Möller 已提交
60
#endif
61
#ifndef OPENSSL_NO_EC
62 63 64 65 66 67 68
    if (pkey->type == EVP_PKEY_EC) {
        int ret = pkey->save_parameters;

        if (mode >= 0)
            pkey->save_parameters = mode;
        return (ret);
    }
69
#endif
70 71
    return (0);
}
72

R
Richard Levitte 已提交
73
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
74
{
75 76 77 78
    if (to->type == EVP_PKEY_NONE) {
        if (EVP_PKEY_set_type(to, from->type) == 0)
            return 0;
    } else if (to->type != from->type) {
79 80 81 82 83 84 85 86
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
        goto err;
    }

    if (EVP_PKEY_missing_parameters(from)) {
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
        goto err;
    }
87 88 89 90 91 92 93 94

    if (!EVP_PKEY_missing_parameters(to)) {
        if (EVP_PKEY_cmp_parameters(to, from) == 1)
            return 1;
        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
        return 0;
    }

95 96 97 98 99
    if (from->ameth && from->ameth->param_copy)
        return from->ameth->param_copy(to, from);
 err:
    return 0;
}
100

R
Richard Levitte 已提交
101
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
102 103 104 105 106
{
    if (pkey->ameth && pkey->ameth->param_missing)
        return pkey->ameth->param_missing(pkey);
    return 0;
}
107

R
Richard Levitte 已提交
108
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
109 110 111 112 113 114 115
{
    if (a->type != b->type)
        return -1;
    if (a->ameth && a->ameth->param_cmp)
        return a->ameth->param_cmp(a, b);
    return -2;
}
116

R
Richard Levitte 已提交
117
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
{
    if (a->type != b->type)
        return -1;

    if (a->ameth) {
        int ret;
        /* Compare parameters if the algorithm has them */
        if (a->ameth->param_cmp) {
            ret = a->ameth->param_cmp(a, b);
            if (ret <= 0)
                return ret;
        }

        if (a->ameth->pub_cmp)
            return a->ameth->pub_cmp(a, b);
    }

    return -2;
}
137

U
Ulf Möller 已提交
138
EVP_PKEY *EVP_PKEY_new(void)
139
{
F
FdaSilvaYY 已提交
140
    EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
141 142 143

    if (ret == NULL) {
        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
144
        return NULL;
145 146 147 148 149
    }
    ret->type = EVP_PKEY_NONE;
    ret->save_type = EVP_PKEY_NONE;
    ret->references = 1;
    ret->save_parameters = 1;
150 151 152 153 154 155 156
    ret->lock = CRYPTO_THREAD_lock_new();
    if (ret->lock == NULL) {
        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
        OPENSSL_free(ret);
        return NULL;
    }
    return ret;
157 158
}

159
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
160
{
161
    int i;
162 163 164 165 166 167 168

    if (CRYPTO_atomic_add(&pkey->references, 1, &i, pkey->lock) <= 0)
        return 0;

    REF_PRINT_COUNT("EVP_PKEY", pkey);
    REF_ASSERT_ISNT(i < 2);
    return ((i > 1) ? 1 : 0);
169 170
}

171 172 173
/*
 * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
 * is NULL just return 1 or 0 if the algorithm exists.
174 175 176
 */

static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
177 178 179 180 181 182 183 184 185 186 187 188
{
    const EVP_PKEY_ASN1_METHOD *ameth;
    ENGINE *e = NULL;
    if (pkey) {
        if (pkey->pkey.ptr)
            EVP_PKEY_free_it(pkey);
        /*
         * If key type matches and a method exists then this lookup has
         * succeeded once so just indicate success.
         */
        if ((type == pkey->save_type) && pkey->ameth)
            return 1;
189
#ifndef OPENSSL_NO_ENGINE
190
        /* If we have an ENGINE release it */
R
Rich Salz 已提交
191 192
        ENGINE_finish(pkey->engine);
        pkey->engine = NULL;
193
#endif
194 195 196 197 198
    }
    if (str)
        ameth = EVP_PKEY_asn1_find_str(&e, str, len);
    else
        ameth = EVP_PKEY_asn1_find(&e, type);
199
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
200
    if (pkey == NULL)
201
        ENGINE_finish(e);
202
#endif
R
Rich Salz 已提交
203
    if (ameth == NULL) {
204 205 206 207 208 209 210 211 212 213 214 215
        EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
        return 0;
    }
    if (pkey) {
        pkey->ameth = ameth;
        pkey->engine = e;

        pkey->type = pkey->ameth->pkey_id;
        pkey->save_type = type;
    }
    return 1;
}
216 217

int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
218 219 220
{
    return pkey_set_type(pkey, type, NULL, -1);
}
221 222

int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
223 224 225
{
    return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
}
226 227

int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
228
{
E
Emilia Kasper 已提交
229
    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
230 231 232 233
        return 0;
    pkey->pkey.ptr = key;
    return (key != NULL);
}
234

D
Dr. Stephen Henson 已提交
235
void *EVP_PKEY_get0(const EVP_PKEY *pkey)
236 237 238
{
    return pkey->pkey.ptr;
}
239

240 241 242 243 244 245 246 247 248 249 250 251
const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
{
    ASN1_OCTET_STRING *os = NULL;
    if (pkey->type != EVP_PKEY_HMAC) {
        EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
        return NULL;
    }
    os = EVP_PKEY_get0(pkey);
    *len = os->length;
    return os->data;
}

252
#ifndef OPENSSL_NO_RSA
253
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
254
{
255 256 257 258
    int ret = EVP_PKEY_assign_RSA(pkey, key);
    if (ret)
        RSA_up_ref(key);
    return ret;
259 260
}

261
RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
262 263
{
    if (pkey->type != EVP_PKEY_RSA) {
264
        EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
265 266 267
        return NULL;
    }
    return pkey->pkey.rsa;
268
}
269 270 271 272 273 274 275 276

RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
{
    RSA *ret = EVP_PKEY_get0_RSA(pkey);
    if (ret != NULL)
        RSA_up_ref(ret);
    return ret;
}
277 278
#endif

279
#ifndef OPENSSL_NO_DSA
280
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
281
{
282 283 284 285
    int ret = EVP_PKEY_assign_DSA(pkey, key);
    if (ret)
        DSA_up_ref(key);
    return ret;
286 287
}

288
DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
289 290
{
    if (pkey->type != EVP_PKEY_DSA) {
291
        EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
292 293 294
        return NULL;
    }
    return pkey->pkey.dsa;
295
}
296 297 298 299 300 301 302 303

DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
{
    DSA *ret = EVP_PKEY_get0_DSA(pkey);
    if (ret != NULL)
        DSA_up_ref(ret);
    return ret;
}
304 305
#endif

306
#ifndef OPENSSL_NO_EC
B
Bodo Möller 已提交
307

308
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
B
Bodo Möller 已提交
309
{
310 311 312 313
    int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
    if (ret)
        EC_KEY_up_ref(key);
    return ret;
B
Bodo Möller 已提交
314 315
}

316
EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
B
Bodo Möller 已提交
317
{
318
    if (pkey->type != EVP_PKEY_EC) {
319
        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
320 321 322
        return NULL;
    }
    return pkey->pkey.ec;
B
Bodo Möller 已提交
323
}
324 325 326 327 328 329 330 331

EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
{
    EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
    if (ret != NULL)
        EC_KEY_up_ref(ret);
    return ret;
}
B
Bodo Möller 已提交
332 333
#endif

334
#ifndef OPENSSL_NO_DH
335

336
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
337
{
338 339 340 341
    int ret = EVP_PKEY_assign_DH(pkey, key);
    if (ret)
        DH_up_ref(key);
    return ret;
342 343
}

344
DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
345 346
{
    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
347
        EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
348 349 350
        return NULL;
    }
    return pkey->pkey.dh;
351
}
352 353 354 355 356 357 358 359

DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
{
    DH *ret = EVP_PKEY_get0_DH(pkey);
    if (ret != NULL)
        DH_up_ref(ret);
    return ret;
}
360 361
#endif

U
Ulf Möller 已提交
362
int EVP_PKEY_type(int type)
363 364 365 366 367 368 369 370 371
{
    int ret;
    const EVP_PKEY_ASN1_METHOD *ameth;
    ENGINE *e;
    ameth = EVP_PKEY_asn1_find(&e, type);
    if (ameth)
        ret = ameth->pkey_id;
    else
        ret = NID_undef;
372
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
373
    ENGINE_finish(e);
374
#endif
375 376
    return ret;
}
377

378
int EVP_PKEY_id(const EVP_PKEY *pkey)
379 380 381
{
    return pkey->type;
}
382 383

int EVP_PKEY_base_id(const EVP_PKEY *pkey)
384 385 386
{
    return EVP_PKEY_type(pkey->type);
}
387

U
Ulf Möller 已提交
388
void EVP_PKEY_free(EVP_PKEY *x)
389 390
{
    int i;
391

392 393
    if (x == NULL)
        return;
394

395
    CRYPTO_atomic_add(&x->references, -1, &i, x->lock);
R
Rich Salz 已提交
396
    REF_PRINT_COUNT("EVP_PKEY", x);
397 398
    if (i > 0)
        return;
R
Rich Salz 已提交
399
    REF_ASSERT_ISNT(i < 0);
400
    EVP_PKEY_free_it(x);
R
Rich Salz 已提交
401
    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
402 403
    OPENSSL_free(x);
}
404

U
Ulf Möller 已提交
405
static void EVP_PKEY_free_it(EVP_PKEY *x)
406
{
R
Rich Salz 已提交
407
    /* internal function; x is never NULL */
408 409 410 411
    if (x->ameth && x->ameth->pkey_free) {
        x->ameth->pkey_free(x);
        x->pkey.ptr = NULL;
    }
412
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
413 414
    ENGINE_finish(x->engine);
    x->engine = NULL;
415
#endif
416
    CRYPTO_THREAD_lock_free(x->lock);
417
}
418

419
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
420 421 422 423 424 425 426
                     const char *kstr)
{
    BIO_indent(out, indent, 128);
    BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
               kstr, OBJ_nid2ln(pkey->type));
    return 1;
}
427 428

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
429 430 431 432 433 434 435
                          int indent, ASN1_PCTX *pctx)
{
    if (pkey->ameth && pkey->ameth->pub_print)
        return pkey->ameth->pub_print(out, pkey, indent, pctx);

    return unsup_alg(out, pkey, indent, "Public Key");
}
436 437

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
438 439 440 441 442 443 444
                           int indent, ASN1_PCTX *pctx)
{
    if (pkey->ameth && pkey->ameth->priv_print)
        return pkey->ameth->priv_print(out, pkey, indent, pctx);

    return unsup_alg(out, pkey, indent, "Private Key");
}
445 446

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
447 448 449 450 451 452
                          int indent, ASN1_PCTX *pctx)
{
    if (pkey->ameth && pkey->ameth->param_print)
        return pkey->ameth->param_print(out, pkey, indent, pctx);
    return unsup_alg(out, pkey, indent, "Parameters");
}
453

D
Dr. Stephen Henson 已提交
454
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
455
{
D
Dr. Stephen Henson 已提交
456
    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
457
        return -2;
D
Dr. Stephen Henson 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
    return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
}

int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
{
    return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
}

int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
                               const unsigned char *pt, size_t ptlen)
{
    if (ptlen > INT_MAX)
        return 0;
    if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
                           (void *)pt) <= 0)
        return 0;
    return 1;
}

size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
{
    int rv;
    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
    if (rv <= 0)
        return 0;
    return rv;
484
}