p_lib.c 18.3 KB
Newer Older
R
Rich Salz 已提交
1
/*
M
Matt Caswell 已提交
2
 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
R
Rich Salz 已提交
5 6 7
 * 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"
12
#include "internal/refcount.h"
B
Bodo Möller 已提交
13 14
#include <openssl/bn.h>
#include <openssl/err.h>
15 16 17
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
R
Rich Salz 已提交
18 19 20
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/dh.h>
21
#include <openssl/cmac.h>
R
Rich Salz 已提交
22
#include <openssl/engine.h>
23 24
#include <openssl/params.h>
#include <openssl/core_names.h>
25

26
#include "internal/asn1_int.h"
D
Dr. Stephen Henson 已提交
27
#include "internal/evp_int.h"
28
#include "internal/provider.h"
29

30
static void EVP_PKEY_free_it(EVP_PKEY *x);
31

32
int EVP_PKEY_bits(const EVP_PKEY *pkey)
33 34 35 36 37
{
    if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
        return pkey->ameth->pkey_bits(pkey);
    return 0;
}
38

39
int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
40 41 42 43 44 45 46
{
    if (pkey == NULL)
        return 0;
    if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
        return -2;
    return pkey->ameth->pkey_security_bits(pkey);
}
47

48
int EVP_PKEY_size(const EVP_PKEY *pkey)
49 50 51 52 53
{
    if (pkey && pkey->ameth && pkey->ameth->pkey_size)
        return pkey->ameth->pkey_size(pkey);
    return 0;
}
54

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

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

        if (mode >= 0)
            pkey->save_parameters = mode;
K
KaoruToda 已提交
72
        return ret;
73
    }
74
#endif
K
KaoruToda 已提交
75
    return 0;
76
}
77

R
Richard Levitte 已提交
78
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
79
{
80 81 82 83
    if (to->type == EVP_PKEY_NONE) {
        if (EVP_PKEY_set_type(to, from->type) == 0)
            return 0;
    } else if (to->type != from->type) {
84 85 86 87 88 89 90 91
        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;
    }
92 93 94 95 96 97 98 99

    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;
    }

100 101 102 103 104
    if (from->ameth && from->ameth->param_copy)
        return from->ameth->param_copy(to, from);
 err:
    return 0;
}
105

R
Richard Levitte 已提交
106
int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
107 108 109 110 111
{
    if (pkey->ameth && pkey->ameth->param_missing)
        return pkey->ameth->param_missing(pkey);
    return 0;
}
112

R
Richard Levitte 已提交
113
int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
114 115 116 117 118 119 120
{
    if (a->type != b->type)
        return -1;
    if (a->ameth && a->ameth->param_cmp)
        return a->ameth->param_cmp(a, b);
    return -2;
}
121

R
Richard Levitte 已提交
122
int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
{
    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;
}
142

U
Ulf Möller 已提交
143
EVP_PKEY *EVP_PKEY_new(void)
144
{
F
FdaSilvaYY 已提交
145
    EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
146 147 148

    if (ret == NULL) {
        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
149
        return NULL;
150 151 152 153 154
    }
    ret->type = EVP_PKEY_NONE;
    ret->save_type = EVP_PKEY_NONE;
    ret->references = 1;
    ret->save_parameters = 1;
155 156 157 158 159 160 161
    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;
162 163
}

164
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
165
{
166
    int i;
167

168
    if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
169 170 171 172 173
        return 0;

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

176 177 178
/*
 * 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.
179 180
 */

181 182
static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
                         int len)
183 184
{
    const EVP_PKEY_ASN1_METHOD *ameth;
185 186
    ENGINE **eptr = (e == NULL) ? &e :  NULL;

187 188 189 190 191 192 193 194 195
    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;
196
#ifndef OPENSSL_NO_ENGINE
197
        /* If we have ENGINEs release them */
R
Rich Salz 已提交
198 199
        ENGINE_finish(pkey->engine);
        pkey->engine = NULL;
200 201
        ENGINE_finish(pkey->pmeth_engine);
        pkey->pmeth_engine = NULL;
202
#endif
203 204
    }
    if (str)
205
        ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
206
    else
207
        ameth = EVP_PKEY_asn1_find(eptr, type);
208
#ifndef OPENSSL_NO_ENGINE
209
    if (pkey == NULL && eptr != NULL)
210
        ENGINE_finish(e);
211
#endif
R
Rich Salz 已提交
212
    if (ameth == NULL) {
213 214 215 216 217 218 219 220 221 222 223 224
        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;
}
225

226 227 228
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
                                       const unsigned char *priv,
                                       size_t len)
229 230 231 232 233 234 235 236 237 238
{
    EVP_PKEY *ret = EVP_PKEY_new();

    if (ret == NULL
            || !pkey_set_type(ret, e, type, NULL, -1)) {
        /* EVPerr already called */
        goto err;
    }

    if (ret->ameth->set_priv_key == NULL) {
239
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
240 241 242 243 244
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        goto err;
    }

    if (!ret->ameth->set_priv_key(ret, priv, len)) {
245
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);
246 247 248 249 250 251 252 253 254 255
        goto err;
    }

    return ret;

 err:
    EVP_PKEY_free(ret);
    return NULL;
}

256 257 258
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
                                      const unsigned char *pub,
                                      size_t len)
259 260 261 262 263 264 265 266 267 268
{
    EVP_PKEY *ret = EVP_PKEY_new();

    if (ret == NULL
            || !pkey_set_type(ret, e, type, NULL, -1)) {
        /* EVPerr already called */
        goto err;
    }

    if (ret->ameth->set_pub_key == NULL) {
269
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
270 271 272 273 274
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        goto err;
    }

    if (!ret->ameth->set_pub_key(ret, pub, len)) {
275
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED);
276 277 278 279 280 281 282 283 284 285
        goto err;
    }

    return ret;

 err:
    EVP_PKEY_free(ret);
    return NULL;
}

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
                                 size_t *len)
{
     if (pkey->ameth->get_priv_key == NULL) {
        EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

    if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
        EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED);
        return 0;
    }

    return 1;
}

int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
                                size_t *len)
{
     if (pkey->ameth->get_pub_key == NULL) {
        EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        return 0;
    }

    if (!pkey->ameth->get_pub_key(pkey, pub, len)) {
        EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY, EVP_R_GET_RAW_KEY_FAILED);
        return 0;
    }

    return 1;
}

320 321 322
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                size_t len, const EVP_CIPHER *cipher)
{
M
Matt Caswell 已提交
323
#ifndef OPENSSL_NO_CMAC
324 325 326 327 328
    const char *engine_name = e != NULL ? ENGINE_get_name(e) : NULL;
    const char *cipher_name = EVP_CIPHER_name(cipher);
    const OSSL_PROVIDER *prov = EVP_CIPHER_provider(cipher);
    OPENSSL_CTX *libctx =
        prov == NULL ? NULL : ossl_provider_library_context(prov);
329
    EVP_PKEY *ret = EVP_PKEY_new();
330
    EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
331 332 333
    EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
    OSSL_PARAM params[4];
    size_t paramsn = 0;
334 335 336 337 338 339 340 341

    if (ret == NULL
            || cmctx == NULL
            || !pkey_set_type(ret, e, EVP_PKEY_CMAC, NULL, -1)) {
        /* EVPerr already called */
        goto err;
    }

342 343 344 345 346 347
    if (engine_name != NULL)
        params[paramsn++] =
            OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_ENGINE,
                                             (char *)engine_name,
                                             strlen(engine_name) + 1);
    params[paramsn++] =
348
        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
349 350 351 352 353 354 355 356
                                         (char *)cipher_name,
                                         strlen(cipher_name) + 1);
    params[paramsn++] =
        OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
                                          (char *)priv, len);
    params[paramsn] = OSSL_PARAM_construct_end();

    if (!EVP_MAC_CTX_set_params(cmctx, params)) {
357 358 359 360 361 362 363 364 365
        EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED);
        goto err;
    }

    ret->pkey.ptr = cmctx;
    return ret;

 err:
    EVP_PKEY_free(ret);
366
    EVP_MAC_CTX_free(cmctx);
367
    EVP_MAC_free(cmac);
368
    return NULL;
M
Matt Caswell 已提交
369 370 371 372 373
#else
    EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
           EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    return NULL;
#endif
374
}
375

376
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
377
{
378
    return pkey_set_type(pkey, NULL, type, NULL, -1);
379
}
380 381

int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
382
{
383
    return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
384
}
J
Jack Lloyd 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404

int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type)
{
    if (pkey->type == type) {
        return 1; /* it already is that type */
    }

    /*
     * The application is requesting to alias this to a different pkey type,
     * but not one that resolves to the base type.
     */
    if (EVP_PKEY_type(type) != EVP_PKEY_base_id(pkey)) {
        EVPerr(EVP_F_EVP_PKEY_SET_ALIAS_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
        return 0;
    }

    pkey->type = type;
    return 1;
}

405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
#ifndef OPENSSL_NO_ENGINE
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e)
{
    if (e != NULL) {
        if (!ENGINE_init(e)) {
            EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, ERR_R_ENGINE_LIB);
            return 0;
        }
        if (ENGINE_get_pkey_meth(e, pkey->type) == NULL) {
            ENGINE_finish(e);
            EVPerr(EVP_F_EVP_PKEY_SET1_ENGINE, EVP_R_UNSUPPORTED_ALGORITHM);
            return 0;
        }
    }
    ENGINE_finish(pkey->pmeth_engine);
    pkey->pmeth_engine = e;
    return 1;
}
423 424 425 426 427

ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
{
    return pkey->engine;
}
428
#endif
429
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
430
{
E
Emilia Kasper 已提交
431
    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
432 433 434 435
        return 0;
    pkey->pkey.ptr = key;
    return (key != NULL);
}
436

D
Dr. Stephen Henson 已提交
437
void *EVP_PKEY_get0(const EVP_PKEY *pkey)
438 439 440
{
    return pkey->pkey.ptr;
}
441

442 443 444 445 446 447 448 449 450 451 452 453
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;
}

454 455 456 457 458 459 460 461 462 463 464 465 466 467
#ifndef OPENSSL_NO_POLY1305
const unsigned char *EVP_PKEY_get0_poly1305(const EVP_PKEY *pkey, size_t *len)
{
    ASN1_OCTET_STRING *os = NULL;
    if (pkey->type != EVP_PKEY_POLY1305) {
        EVPerr(EVP_F_EVP_PKEY_GET0_POLY1305, EVP_R_EXPECTING_A_POLY1305_KEY);
        return NULL;
    }
    os = EVP_PKEY_get0(pkey);
    *len = os->length;
    return os->data;
}
#endif

468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
#ifndef OPENSSL_NO_SIPHASH
const unsigned char *EVP_PKEY_get0_siphash(const EVP_PKEY *pkey, size_t *len)
{
    ASN1_OCTET_STRING *os = NULL;

    if (pkey->type != EVP_PKEY_SIPHASH) {
        EVPerr(EVP_F_EVP_PKEY_GET0_SIPHASH, EVP_R_EXPECTING_A_SIPHASH_KEY);
        return NULL;
    }
    os = EVP_PKEY_get0(pkey);
    *len = os->length;
    return os->data;
}
#endif

483
#ifndef OPENSSL_NO_RSA
484
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
485
{
486 487 488 489
    int ret = EVP_PKEY_assign_RSA(pkey, key);
    if (ret)
        RSA_up_ref(key);
    return ret;
490 491
}

492
RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey)
493 494
{
    if (pkey->type != EVP_PKEY_RSA) {
495
        EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
496 497 498
        return NULL;
    }
    return pkey->pkey.rsa;
499
}
500 501 502 503 504 505 506 507

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

510
#ifndef OPENSSL_NO_DSA
511
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
512
{
513 514 515 516
    int ret = EVP_PKEY_assign_DSA(pkey, key);
    if (ret)
        DSA_up_ref(key);
    return ret;
517 518
}

519
DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
520 521
{
    if (pkey->type != EVP_PKEY_DSA) {
522
        EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
523 524 525
        return NULL;
    }
    return pkey->pkey.dsa;
526
}
527 528 529 530 531 532 533 534

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

537
#ifndef OPENSSL_NO_EC
B
Bodo Möller 已提交
538

539
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
B
Bodo Möller 已提交
540
{
541 542 543 544
    int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
    if (ret)
        EC_KEY_up_ref(key);
    return ret;
B
Bodo Möller 已提交
545 546
}

547
EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
B
Bodo Möller 已提交
548
{
549
    if (pkey->type != EVP_PKEY_EC) {
550
        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
551 552 553
        return NULL;
    }
    return pkey->pkey.ec;
B
Bodo Möller 已提交
554
}
555 556 557 558 559 560 561 562

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 已提交
563 564
#endif

565
#ifndef OPENSSL_NO_DH
566

567
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
568
{
569 570 571 572
    int ret = EVP_PKEY_assign_DH(pkey, key);
    if (ret)
        DH_up_ref(key);
    return ret;
573 574
}

575
DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey)
576 577
{
    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
578
        EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
579 580 581
        return NULL;
    }
    return pkey->pkey.dh;
582
}
583 584 585 586 587 588 589 590

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

U
Ulf Möller 已提交
593
int EVP_PKEY_type(int type)
594 595 596 597 598 599 600 601 602
{
    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;
603
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
604
    ENGINE_finish(e);
605
#endif
606 607
    return ret;
}
608

609
int EVP_PKEY_id(const EVP_PKEY *pkey)
610 611 612
{
    return pkey->type;
}
613 614

int EVP_PKEY_base_id(const EVP_PKEY *pkey)
615 616 617
{
    return EVP_PKEY_type(pkey->type);
}
618

U
Ulf Möller 已提交
619
void EVP_PKEY_free(EVP_PKEY *x)
620 621
{
    int i;
622

623 624
    if (x == NULL)
        return;
625

626
    CRYPTO_DOWN_REF(&x->references, &i, x->lock);
R
Rich Salz 已提交
627
    REF_PRINT_COUNT("EVP_PKEY", x);
628 629
    if (i > 0)
        return;
R
Rich Salz 已提交
630
    REF_ASSERT_ISNT(i < 0);
631
    EVP_PKEY_free_it(x);
632
    CRYPTO_THREAD_lock_free(x->lock);
R
Rich Salz 已提交
633
    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
634 635
    OPENSSL_free(x);
}
636

U
Ulf Möller 已提交
637
static void EVP_PKEY_free_it(EVP_PKEY *x)
638
{
R
Rich Salz 已提交
639
    /* internal function; x is never NULL */
640 641 642

    evp_keymgmt_clear_pkey_cache(x);

643 644 645 646
    if (x->ameth && x->ameth->pkey_free) {
        x->ameth->pkey_free(x);
        x->pkey.ptr = NULL;
    }
647
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
648 649
    ENGINE_finish(x->engine);
    x->engine = NULL;
650 651
    ENGINE_finish(x->pmeth_engine);
    x->pmeth_engine = NULL;
652
#endif
653
}
654

655
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
656 657 658 659 660 661 662
                     const char *kstr)
{
    BIO_indent(out, indent, 128);
    BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
               kstr, OBJ_nid2ln(pkey->type));
    return 1;
}
663 664

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
665 666 667 668 669 670 671
                          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");
}
672 673

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
674 675 676 677 678 679 680
                           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");
}
681 682

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
683 684 685 686 687 688
                          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");
}
689

D
Dr. Stephen Henson 已提交
690
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
691
{
D
Dr. Stephen Henson 已提交
692
    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
693
        return -2;
D
Dr. Stephen Henson 已提交
694 695 696 697 698 699 700 701
    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);
}

702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
{
    int rv, default_nid;

    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SUPPORTS_MD_NID, nid, NULL);
    if (rv == -2) {
        /*
         * If there is a mandatory default digest and this isn't it, then
         * the answer is 'no'.
         */
        rv = EVP_PKEY_get_default_digest_nid(pkey, &default_nid);
        if (rv == 2)
            return (nid == default_nid);
        /* zero is an error from EVP_PKEY_get_default_digest_nid() */
        if (rv == 0)
            return -1;
    }
    return rv;
}

D
Dr. Stephen Henson 已提交
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
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;
740
}