p_lib.c 17.1 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 "internal/asn1_int.h"
D
Dr. Stephen Henson 已提交
25
#include "internal/evp_int.h"
26

27
static void EVP_PKEY_free_it(EVP_PKEY *x);
28

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

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

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

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

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

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

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

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

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

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

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

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

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

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

161
int EVP_PKEY_up_ref(EVP_PKEY *pkey)
162
{
163
    int i;
164

165
    if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
166 167 168 169 170
        return 0;

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

173 174 175
/*
 * 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.
176 177
 */

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

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

223 224 225
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
                                       const unsigned char *priv,
                                       size_t len)
226 227 228 229 230 231 232 233 234 235
{
    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) {
236
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
237 238 239 240 241
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        goto err;
    }

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

    return ret;

 err:
    EVP_PKEY_free(ret);
    return NULL;
}

253 254 255
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
                                      const unsigned char *pub,
                                      size_t len)
256 257 258 259 260 261 262 263 264 265
{
    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) {
266
        EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
267 268 269 270 271
               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
        goto err;
    }

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

    return ret;

 err:
    EVP_PKEY_free(ret);
    return NULL;
}

283 284 285 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
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;
}

317 318 319
EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv,
                                size_t len, const EVP_CIPHER *cipher)
{
M
Matt Caswell 已提交
320
#ifndef OPENSSL_NO_CMAC
321
    EVP_PKEY *ret = EVP_PKEY_new();
322
    EVP_MAC_CTX *cmctx = EVP_MAC_CTX_new_id(EVP_MAC_CMAC);
323 324 325 326 327 328 329 330

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

331 332 333
    if (EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_ENGINE, e) <= 0
        || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_CIPHER, cipher) <= 0
        || EVP_MAC_ctrl(cmctx, EVP_MAC_CTRL_SET_KEY, priv, len) <= 0) {
334 335 336 337 338 339 340 341 342
        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);
343
    EVP_MAC_CTX_free(cmctx);
344
    return NULL;
M
Matt Caswell 已提交
345 346 347 348 349
#else
    EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY,
           EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
    return NULL;
#endif
350
}
351

352
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
353
{
354
    return pkey_set_type(pkey, NULL, type, NULL, -1);
355
}
356 357

int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
358
{
359
    return pkey_set_type(pkey, NULL, EVP_PKEY_NONE, str, len);
360
}
J
Jack Lloyd 已提交
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380

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

381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
#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;
}
#endif
400
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
401
{
E
Emilia Kasper 已提交
402
    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
403 404 405 406
        return 0;
    pkey->pkey.ptr = key;
    return (key != NULL);
}
407

D
Dr. Stephen Henson 已提交
408
void *EVP_PKEY_get0(const EVP_PKEY *pkey)
409 410 411
{
    return pkey->pkey.ptr;
}
412

413 414 415 416 417 418 419 420 421 422 423 424
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;
}

425 426 427 428 429 430 431 432 433 434 435 436 437 438
#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

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453
#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

454
#ifndef OPENSSL_NO_RSA
455
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
456
{
457 458 459 460
    int ret = EVP_PKEY_assign_RSA(pkey, key);
    if (ret)
        RSA_up_ref(key);
    return ret;
461 462
}

463
RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
464 465
{
    if (pkey->type != EVP_PKEY_RSA) {
466
        EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
467 468 469
        return NULL;
    }
    return pkey->pkey.rsa;
470
}
471 472 473 474 475 476 477 478

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

481
#ifndef OPENSSL_NO_DSA
482
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
483
{
484 485 486 487
    int ret = EVP_PKEY_assign_DSA(pkey, key);
    if (ret)
        DSA_up_ref(key);
    return ret;
488 489
}

490
DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
491 492
{
    if (pkey->type != EVP_PKEY_DSA) {
493
        EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
494 495 496
        return NULL;
    }
    return pkey->pkey.dsa;
497
}
498 499 500 501 502 503 504 505

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

508
#ifndef OPENSSL_NO_EC
B
Bodo Möller 已提交
509

510
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
B
Bodo Möller 已提交
511
{
512 513 514 515
    int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
    if (ret)
        EC_KEY_up_ref(key);
    return ret;
B
Bodo Möller 已提交
516 517
}

518
EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
B
Bodo Möller 已提交
519
{
520
    if (pkey->type != EVP_PKEY_EC) {
521
        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
522 523 524
        return NULL;
    }
    return pkey->pkey.ec;
B
Bodo Möller 已提交
525
}
526 527 528 529 530 531 532 533

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 已提交
534 535
#endif

536
#ifndef OPENSSL_NO_DH
537

538
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
539
{
540 541 542 543
    int ret = EVP_PKEY_assign_DH(pkey, key);
    if (ret)
        DH_up_ref(key);
    return ret;
544 545
}

546
DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
547 548
{
    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
549
        EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
550 551 552
        return NULL;
    }
    return pkey->pkey.dh;
553
}
554 555 556 557 558 559 560 561

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

U
Ulf Möller 已提交
564
int EVP_PKEY_type(int type)
565 566 567 568 569 570 571 572 573
{
    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;
574
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
575
    ENGINE_finish(e);
576
#endif
577 578
    return ret;
}
579

580
int EVP_PKEY_id(const EVP_PKEY *pkey)
581 582 583
{
    return pkey->type;
}
584 585

int EVP_PKEY_base_id(const EVP_PKEY *pkey)
586 587 588
{
    return EVP_PKEY_type(pkey->type);
}
589

U
Ulf Möller 已提交
590
void EVP_PKEY_free(EVP_PKEY *x)
591 592
{
    int i;
593

594 595
    if (x == NULL)
        return;
596

597
    CRYPTO_DOWN_REF(&x->references, &i, x->lock);
R
Rich Salz 已提交
598
    REF_PRINT_COUNT("EVP_PKEY", x);
599 600
    if (i > 0)
        return;
R
Rich Salz 已提交
601
    REF_ASSERT_ISNT(i < 0);
602
    EVP_PKEY_free_it(x);
603
    CRYPTO_THREAD_lock_free(x->lock);
R
Rich Salz 已提交
604
    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
605 606
    OPENSSL_free(x);
}
607

U
Ulf Möller 已提交
608
static void EVP_PKEY_free_it(EVP_PKEY *x)
609
{
R
Rich Salz 已提交
610
    /* internal function; x is never NULL */
611 612 613 614
    if (x->ameth && x->ameth->pkey_free) {
        x->ameth->pkey_free(x);
        x->pkey.ptr = NULL;
    }
615
#ifndef OPENSSL_NO_ENGINE
R
Rich Salz 已提交
616 617
    ENGINE_finish(x->engine);
    x->engine = NULL;
618 619
    ENGINE_finish(x->pmeth_engine);
    x->pmeth_engine = NULL;
620
#endif
621
}
622

623
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
624 625 626 627 628 629 630
                     const char *kstr)
{
    BIO_indent(out, indent, 128);
    BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
               kstr, OBJ_nid2ln(pkey->type));
    return 1;
}
631 632

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
633 634 635 636 637 638 639
                          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");
}
640 641

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
642 643 644 645 646 647 648
                           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");
}
649 650

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
651 652 653 654 655 656
                          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");
}
657

D
Dr. Stephen Henson 已提交
658
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
659
{
D
Dr. Stephen Henson 已提交
660
    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
661
        return -2;
D
Dr. Stephen Henson 已提交
662 663 664 665 666 667 668 669
    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);
}

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
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 已提交
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
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;
708
}