p_lib.c 18.2 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
M
Matt Caswell 已提交
324
# ifndef OPENSSL_NO_ENGINE
325
    const char *engine_id = e != NULL ? ENGINE_get_id(e) : NULL;
M
Matt Caswell 已提交
326
# endif
327 328 329 330
    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);
331
    EVP_PKEY *ret = EVP_PKEY_new();
332
    EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL);
333 334 335
    EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL;
    OSSL_PARAM params[4];
    size_t paramsn = 0;
336 337 338 339 340 341 342 343

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

M
Matt Caswell 已提交
344
# ifndef OPENSSL_NO_ENGINE
345
    if (engine_id != NULL)
346
        params[paramsn++] =
347
            OSSL_PARAM_construct_utf8_string("engine", (char *)engine_id, 0);
M
Matt Caswell 已提交
348 349
# endif

350
    params[paramsn++] =
351
        OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_CIPHER,
352
                                         (char *)cipher_name, 0);
353 354 355 356 357 358
    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)) {
359 360 361 362 363 364 365 366 367
        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);
368
    EVP_MAC_CTX_free(cmctx);
369
    EVP_MAC_free(cmac);
370
    return NULL;
M
Matt Caswell 已提交
371 372 373 374 375
#else
    EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
           EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    return NULL;
#endif
376
}
377

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

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

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

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
#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;
}
425 426 427 428 429

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

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

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

456 457 458 459 460 461 462 463 464 465 466 467 468 469
#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

470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
#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

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

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

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

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

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

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

539
#ifndef OPENSSL_NO_EC
B
Bodo Möller 已提交
540

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

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

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 已提交
565 566
#endif

567
#ifndef OPENSSL_NO_DH
568

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

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

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

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

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

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

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

625 626
    if (x == NULL)
        return;
627

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

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

    evp_keymgmt_clear_pkey_cache(x);

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

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

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

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

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

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

704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723
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 已提交
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
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;
742
}