155714Skris/* crypto/evp/p_lib.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 855714Skris * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1555714Skris * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 2255714Skris * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 4055714Skris * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 5255714Skris * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 5955714Skris#include <stdio.h> 6055714Skris#include "cryptlib.h" 61160814Ssimon#include <openssl/bn.h> 62160814Ssimon#include <openssl/err.h> 6355714Skris#include <openssl/objects.h> 6455714Skris#include <openssl/evp.h> 6555714Skris#include <openssl/asn1_mac.h> 6655714Skris#include <openssl/x509.h> 67160814Ssimon#ifndef OPENSSL_NO_RSA 68160814Ssimon#include <openssl/rsa.h> 69160814Ssimon#endif 70160814Ssimon#ifndef OPENSSL_NO_DSA 71160814Ssimon#include <openssl/dsa.h> 72160814Ssimon#endif 73160814Ssimon#ifndef OPENSSL_NO_DH 74160814Ssimon#include <openssl/dh.h> 75160814Ssimon#endif 7655714Skris 77238405Sjkim#ifndef OPENSSL_NO_ENGINE 78238405Sjkim#include <openssl/engine.h> 79238405Sjkim#endif 80238405Sjkim 81238405Sjkim#include "asn1_locl.h" 82238405Sjkim 8355714Skrisstatic void EVP_PKEY_free_it(EVP_PKEY *x); 84109998Smarkm 8555714Skrisint EVP_PKEY_bits(EVP_PKEY *pkey) 8655714Skris { 87238405Sjkim if (pkey && pkey->ameth && pkey->ameth->pkey_bits) 88238405Sjkim return pkey->ameth->pkey_bits(pkey); 89238405Sjkim return 0; 9055714Skris } 9155714Skris 9255714Skrisint EVP_PKEY_size(EVP_PKEY *pkey) 9355714Skris { 94238405Sjkim if (pkey && pkey->ameth && pkey->ameth->pkey_size) 95238405Sjkim return pkey->ameth->pkey_size(pkey); 96238405Sjkim return 0; 9755714Skris } 9855714Skris 9955714Skrisint EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) 10055714Skris { 101109998Smarkm#ifndef OPENSSL_NO_DSA 10255714Skris if (pkey->type == EVP_PKEY_DSA) 10355714Skris { 104109998Smarkm int ret=pkey->save_parameters; 10555714Skris 10655714Skris if (mode >= 0) 10755714Skris pkey->save_parameters=mode; 10855714Skris return(ret); 10955714Skris } 11055714Skris#endif 111160814Ssimon#ifndef OPENSSL_NO_EC 112160814Ssimon if (pkey->type == EVP_PKEY_EC) 113160814Ssimon { 114160814Ssimon int ret = pkey->save_parameters; 115160814Ssimon 116160814Ssimon if (mode >= 0) 117160814Ssimon pkey->save_parameters = mode; 118160814Ssimon return(ret); 119160814Ssimon } 120160814Ssimon#endif 12155714Skris return(0); 12255714Skris } 12355714Skris 124160814Ssimonint EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 12555714Skris { 12655714Skris if (to->type != from->type) 12755714Skris { 12855714Skris EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES); 12955714Skris goto err; 13055714Skris } 13155714Skris 13255714Skris if (EVP_PKEY_missing_parameters(from)) 13355714Skris { 13459191Skris EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); 13555714Skris goto err; 13655714Skris } 137238405Sjkim if (from->ameth && from->ameth->param_copy) 138238405Sjkim return from->ameth->param_copy(to, from); 13955714Skriserr: 140238405Sjkim return 0; 14155714Skris } 14255714Skris 143160814Ssimonint EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) 14455714Skris { 145238405Sjkim if (pkey->ameth && pkey->ameth->param_missing) 146238405Sjkim return pkey->ameth->param_missing(pkey); 147238405Sjkim return 0; 14855714Skris } 14955714Skris 150160814Ssimonint EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 15155714Skris { 152238405Sjkim if (a->type != b->type) 153238405Sjkim return -1; 154238405Sjkim if (a->ameth && a->ameth->param_cmp) 155238405Sjkim return a->ameth->param_cmp(a, b); 156238405Sjkim return -2; 15755714Skris } 15855714Skris 159160814Ssimonint EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 160160814Ssimon { 161160814Ssimon if (a->type != b->type) 162160814Ssimon return -1; 163160814Ssimon 164238405Sjkim if (a->ameth) 165160814Ssimon { 166238405Sjkim int ret; 167238405Sjkim /* Compare parameters if the algorithm has them */ 168238405Sjkim if (a->ameth->param_cmp) 169160814Ssimon { 170238405Sjkim ret = a->ameth->param_cmp(a, b); 171238405Sjkim if (ret <= 0) 172238405Sjkim return ret; 173160814Ssimon } 174238405Sjkim 175238405Sjkim if (a->ameth->pub_cmp) 176238405Sjkim return a->ameth->pub_cmp(a, b); 177160814Ssimon } 178160814Ssimon 179238405Sjkim return -2; 180160814Ssimon } 181160814Ssimon 18255714SkrisEVP_PKEY *EVP_PKEY_new(void) 18355714Skris { 18455714Skris EVP_PKEY *ret; 18555714Skris 18668651Skris ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY)); 18755714Skris if (ret == NULL) 18855714Skris { 18955714Skris EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE); 19055714Skris return(NULL); 19155714Skris } 19255714Skris ret->type=EVP_PKEY_NONE; 193238405Sjkim ret->save_type=EVP_PKEY_NONE; 19455714Skris ret->references=1; 195238405Sjkim ret->ameth=NULL; 196238405Sjkim ret->engine=NULL; 19755714Skris ret->pkey.ptr=NULL; 19855714Skris ret->attributes=NULL; 19955714Skris ret->save_parameters=1; 20055714Skris return(ret); 20155714Skris } 20255714Skris 203238405Sjkim/* Setup a public key ASN1 method and ENGINE from a NID or a string. 204238405Sjkim * If pkey is NULL just return 1 or 0 if the algorithm exists. 205238405Sjkim */ 206238405Sjkim 207238405Sjkimstatic int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) 20855714Skris { 209238405Sjkim const EVP_PKEY_ASN1_METHOD *ameth; 210238405Sjkim ENGINE *e = NULL; 211238405Sjkim if (pkey) 212238405Sjkim { 213238405Sjkim if (pkey->pkey.ptr) 214238405Sjkim EVP_PKEY_free_it(pkey); 215238405Sjkim /* If key type matches and a method exists then this 216238405Sjkim * lookup has succeeded once so just indicate success. 217238405Sjkim */ 218238405Sjkim if ((type == pkey->save_type) && pkey->ameth) 219238405Sjkim return 1; 220238405Sjkim#ifndef OPENSSL_NO_ENGINE 221238405Sjkim /* If we have an ENGINE release it */ 222238405Sjkim if (pkey->engine) 223238405Sjkim { 224238405Sjkim ENGINE_finish(pkey->engine); 225238405Sjkim pkey->engine = NULL; 226238405Sjkim } 227238405Sjkim#endif 228238405Sjkim } 229238405Sjkim if (str) 230238405Sjkim ameth = EVP_PKEY_asn1_find_str(&e, str, len); 231238405Sjkim else 232238405Sjkim ameth = EVP_PKEY_asn1_find(&e, type); 233238405Sjkim#ifndef OPENSSL_NO_ENGINE 234238405Sjkim if (!pkey && e) 235238405Sjkim ENGINE_finish(e); 236238405Sjkim#endif 237238405Sjkim if (!ameth) 238238405Sjkim { 239238405Sjkim EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); 240238405Sjkim return 0; 241238405Sjkim } 242238405Sjkim if (pkey) 243238405Sjkim { 244238405Sjkim pkey->ameth = ameth; 245238405Sjkim pkey->engine = e; 246238405Sjkim 247238405Sjkim pkey->type = pkey->ameth->pkey_id; 248238405Sjkim pkey->save_type=type; 249238405Sjkim } 250238405Sjkim return 1; 251238405Sjkim } 252238405Sjkim 253238405Sjkimint EVP_PKEY_set_type(EVP_PKEY *pkey, int type) 254238405Sjkim { 255238405Sjkim return pkey_set_type(pkey, type, NULL, -1); 256238405Sjkim } 257238405Sjkim 258238405Sjkimint EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) 259238405Sjkim { 260238405Sjkim return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); 261238405Sjkim } 262238405Sjkim 263238405Sjkimint EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) 264238405Sjkim { 265238405Sjkim if (!EVP_PKEY_set_type(pkey, type)) 266238405Sjkim return 0; 26755714Skris pkey->pkey.ptr=key; 268238405Sjkim return (key != NULL); 26955714Skris } 27055714Skris 271238405Sjkimvoid *EVP_PKEY_get0(EVP_PKEY *pkey) 272238405Sjkim { 273238405Sjkim return pkey->pkey.ptr; 274238405Sjkim } 275238405Sjkim 276109998Smarkm#ifndef OPENSSL_NO_RSA 27759191Skrisint EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) 27859191Skris{ 27959191Skris int ret = EVP_PKEY_assign_RSA(pkey, key); 280109998Smarkm if(ret) 281109998Smarkm RSA_up_ref(key); 28259191Skris return ret; 28359191Skris} 28459191Skris 28559191SkrisRSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) 28659191Skris { 28759191Skris if(pkey->type != EVP_PKEY_RSA) { 28859191Skris EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); 28959191Skris return NULL; 29059191Skris } 291109998Smarkm RSA_up_ref(pkey->pkey.rsa); 29259191Skris return pkey->pkey.rsa; 29359191Skris} 29459191Skris#endif 29559191Skris 296109998Smarkm#ifndef OPENSSL_NO_DSA 29759191Skrisint EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) 29859191Skris{ 29959191Skris int ret = EVP_PKEY_assign_DSA(pkey, key); 300109998Smarkm if(ret) 301109998Smarkm DSA_up_ref(key); 30259191Skris return ret; 30359191Skris} 30459191Skris 30559191SkrisDSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) 30659191Skris { 30759191Skris if(pkey->type != EVP_PKEY_DSA) { 30859191Skris EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY); 30959191Skris return NULL; 31059191Skris } 311109998Smarkm DSA_up_ref(pkey->pkey.dsa); 31259191Skris return pkey->pkey.dsa; 31359191Skris} 31459191Skris#endif 31559191Skris 316160814Ssimon#ifndef OPENSSL_NO_EC 317160814Ssimon 318160814Ssimonint EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) 319160814Ssimon{ 320160814Ssimon int ret = EVP_PKEY_assign_EC_KEY(pkey,key); 321160814Ssimon if (ret) 322160814Ssimon EC_KEY_up_ref(key); 323160814Ssimon return ret; 324160814Ssimon} 325160814Ssimon 326160814SsimonEC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) 327160814Ssimon{ 328160814Ssimon if (pkey->type != EVP_PKEY_EC) 329160814Ssimon { 330160814Ssimon EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); 331160814Ssimon return NULL; 332160814Ssimon } 333160814Ssimon EC_KEY_up_ref(pkey->pkey.ec); 334160814Ssimon return pkey->pkey.ec; 335160814Ssimon} 336160814Ssimon#endif 337160814Ssimon 338160814Ssimon 339109998Smarkm#ifndef OPENSSL_NO_DH 34059191Skris 34159191Skrisint EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) 34259191Skris{ 34359191Skris int ret = EVP_PKEY_assign_DH(pkey, key); 344109998Smarkm if(ret) 345109998Smarkm DH_up_ref(key); 34659191Skris return ret; 34759191Skris} 34859191Skris 34959191SkrisDH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) 35059191Skris { 35159191Skris if(pkey->type != EVP_PKEY_DH) { 35259191Skris EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); 35359191Skris return NULL; 35459191Skris } 355109998Smarkm DH_up_ref(pkey->pkey.dh); 35659191Skris return pkey->pkey.dh; 35759191Skris} 35859191Skris#endif 35959191Skris 36055714Skrisint EVP_PKEY_type(int type) 36155714Skris { 362238405Sjkim int ret; 363238405Sjkim const EVP_PKEY_ASN1_METHOD *ameth; 364238405Sjkim ENGINE *e; 365238405Sjkim ameth = EVP_PKEY_asn1_find(&e, type); 366238405Sjkim if (ameth) 367238405Sjkim ret = ameth->pkey_id; 368238405Sjkim else 369238405Sjkim ret = NID_undef; 370238405Sjkim#ifndef OPENSSL_NO_ENGINE 371238405Sjkim if (e) 372238405Sjkim ENGINE_finish(e); 373238405Sjkim#endif 374238405Sjkim return ret; 37555714Skris } 37655714Skris 377238405Sjkimint EVP_PKEY_id(const EVP_PKEY *pkey) 378238405Sjkim { 379238405Sjkim return pkey->type; 380238405Sjkim } 381238405Sjkim 382238405Sjkimint EVP_PKEY_base_id(const EVP_PKEY *pkey) 383238405Sjkim { 384238405Sjkim return EVP_PKEY_type(pkey->type); 385238405Sjkim } 386238405Sjkim 38755714Skrisvoid EVP_PKEY_free(EVP_PKEY *x) 38855714Skris { 38955714Skris int i; 39055714Skris 39155714Skris if (x == NULL) return; 39255714Skris 39355714Skris i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY); 39455714Skris#ifdef REF_PRINT 39555714Skris REF_PRINT("EVP_PKEY",x); 39655714Skris#endif 39755714Skris if (i > 0) return; 39855714Skris#ifdef REF_CHECK 39955714Skris if (i < 0) 40055714Skris { 40155714Skris fprintf(stderr,"EVP_PKEY_free, bad reference count\n"); 40255714Skris abort(); 40355714Skris } 40455714Skris#endif 40555714Skris EVP_PKEY_free_it(x); 406160814Ssimon if (x->attributes) 407160814Ssimon sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); 40868651Skris OPENSSL_free(x); 40955714Skris } 41055714Skris 41155714Skrisstatic void EVP_PKEY_free_it(EVP_PKEY *x) 41255714Skris { 413238405Sjkim if (x->ameth && x->ameth->pkey_free) 41455714Skris { 415238405Sjkim x->ameth->pkey_free(x); 416238405Sjkim x->pkey.ptr = NULL; 417238405Sjkim } 418238405Sjkim#ifndef OPENSSL_NO_ENGINE 419238405Sjkim if (x->engine) 420238405Sjkim { 421238405Sjkim ENGINE_finish(x->engine); 422238405Sjkim x->engine = NULL; 423238405Sjkim } 42455714Skris#endif 42555714Skris } 42655714Skris 427238405Sjkimstatic int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, 428238405Sjkim const char *kstr) 429238405Sjkim { 430238405Sjkim BIO_indent(out, indent, 128); 431238405Sjkim BIO_printf(out, "%s algorithm \"%s\" unsupported\n", 432238405Sjkim kstr, OBJ_nid2ln(pkey->type)); 433238405Sjkim return 1; 434238405Sjkim } 435238405Sjkim 436238405Sjkimint EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, 437238405Sjkim int indent, ASN1_PCTX *pctx) 438238405Sjkim { 439238405Sjkim if (pkey->ameth && pkey->ameth->pub_print) 440238405Sjkim return pkey->ameth->pub_print(out, pkey, indent, pctx); 441238405Sjkim 442238405Sjkim return unsup_alg(out, pkey, indent, "Public Key"); 443238405Sjkim } 444238405Sjkim 445238405Sjkimint EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, 446238405Sjkim int indent, ASN1_PCTX *pctx) 447238405Sjkim { 448238405Sjkim if (pkey->ameth && pkey->ameth->priv_print) 449238405Sjkim return pkey->ameth->priv_print(out, pkey, indent, pctx); 450238405Sjkim 451238405Sjkim return unsup_alg(out, pkey, indent, "Private Key"); 452238405Sjkim } 453238405Sjkim 454238405Sjkimint EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, 455238405Sjkim int indent, ASN1_PCTX *pctx) 456238405Sjkim { 457238405Sjkim if (pkey->ameth && pkey->ameth->param_print) 458238405Sjkim return pkey->ameth->param_print(out, pkey, indent, pctx); 459238405Sjkim return unsup_alg(out, pkey, indent, "Parameters"); 460238405Sjkim } 461238405Sjkim 462238405Sjkimint EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) 463238405Sjkim { 464238405Sjkim if (!pkey->ameth || !pkey->ameth->pkey_ctrl) 465238405Sjkim return -2; 466238405Sjkim return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 467238405Sjkim 0, pnid); 468238405Sjkim } 469238405Sjkim 470