1*0Sstevel@tonic-gate /* crypto/evp/p_lib.c */ 2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*0Sstevel@tonic-gate * All rights reserved. 4*0Sstevel@tonic-gate * 5*0Sstevel@tonic-gate * This package is an SSL implementation written 6*0Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com). 7*0Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as 10*0Sstevel@tonic-gate * the following conditions are aheared to. The following conditions 11*0Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA, 12*0Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*0Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms 14*0Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*0Sstevel@tonic-gate * 16*0Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in 17*0Sstevel@tonic-gate * the code are not to be removed. 18*0Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution 19*0Sstevel@tonic-gate * as the author of the parts of the library used. 20*0Sstevel@tonic-gate * This can be in the form of a textual message at program startup or 21*0Sstevel@tonic-gate * in documentation (online or textual) provided with the package. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without 24*0Sstevel@tonic-gate * modification, are permitted provided that the following conditions 25*0Sstevel@tonic-gate * are met: 26*0Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright 27*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer. 28*0Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright 29*0Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the 30*0Sstevel@tonic-gate * documentation and/or other materials provided with the distribution. 31*0Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software 32*0Sstevel@tonic-gate * must display the following acknowledgement: 33*0Sstevel@tonic-gate * "This product includes cryptographic software written by 34*0Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)" 35*0Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library 36*0Sstevel@tonic-gate * being used are not cryptographic related :-). 37*0Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from 38*0Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement: 39*0Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*0Sstevel@tonic-gate * 41*0Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*0Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*0Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*0Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*0Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*0Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*0Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*0Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*0Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*0Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*0Sstevel@tonic-gate * SUCH DAMAGE. 52*0Sstevel@tonic-gate * 53*0Sstevel@tonic-gate * The licence and distribution terms for any publically available version or 54*0Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be 55*0Sstevel@tonic-gate * copied and put under another distribution licence 56*0Sstevel@tonic-gate * [including the GNU Public Licence.] 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate #include <stdio.h> 60*0Sstevel@tonic-gate #include "cryptlib.h" 61*0Sstevel@tonic-gate #include <openssl/objects.h> 62*0Sstevel@tonic-gate #include <openssl/evp.h> 63*0Sstevel@tonic-gate #include <openssl/asn1_mac.h> 64*0Sstevel@tonic-gate #include <openssl/x509.h> 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate static void EVP_PKEY_free_it(EVP_PKEY *x); 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate int EVP_PKEY_bits(EVP_PKEY *pkey) 69*0Sstevel@tonic-gate { 70*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 71*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_RSA) 72*0Sstevel@tonic-gate return(BN_num_bits(pkey->pkey.rsa->n)); 73*0Sstevel@tonic-gate else 74*0Sstevel@tonic-gate #endif 75*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 76*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 77*0Sstevel@tonic-gate return(BN_num_bits(pkey->pkey.dsa->p)); 78*0Sstevel@tonic-gate #endif 79*0Sstevel@tonic-gate return(0); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate int EVP_PKEY_size(EVP_PKEY *pkey) 83*0Sstevel@tonic-gate { 84*0Sstevel@tonic-gate if (pkey == NULL) 85*0Sstevel@tonic-gate return(0); 86*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 87*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_RSA) 88*0Sstevel@tonic-gate return(RSA_size(pkey->pkey.rsa)); 89*0Sstevel@tonic-gate else 90*0Sstevel@tonic-gate #endif 91*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 92*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 93*0Sstevel@tonic-gate return(DSA_size(pkey->pkey.dsa)); 94*0Sstevel@tonic-gate #endif 95*0Sstevel@tonic-gate return(0); 96*0Sstevel@tonic-gate } 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) 99*0Sstevel@tonic-gate { 100*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 101*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 102*0Sstevel@tonic-gate { 103*0Sstevel@tonic-gate int ret=pkey->save_parameters; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate if (mode >= 0) 106*0Sstevel@tonic-gate pkey->save_parameters=mode; 107*0Sstevel@tonic-gate return(ret); 108*0Sstevel@tonic-gate } 109*0Sstevel@tonic-gate #endif 110*0Sstevel@tonic-gate return(0); 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate int EVP_PKEY_copy_parameters(EVP_PKEY *to, EVP_PKEY *from) 114*0Sstevel@tonic-gate { 115*0Sstevel@tonic-gate if (to->type != from->type) 116*0Sstevel@tonic-gate { 117*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES); 118*0Sstevel@tonic-gate goto err; 119*0Sstevel@tonic-gate } 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate if (EVP_PKEY_missing_parameters(from)) 122*0Sstevel@tonic-gate { 123*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS); 124*0Sstevel@tonic-gate goto err; 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 127*0Sstevel@tonic-gate if (to->type == EVP_PKEY_DSA) 128*0Sstevel@tonic-gate { 129*0Sstevel@tonic-gate BIGNUM *a; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate if ((a=BN_dup(from->pkey.dsa->p)) == NULL) goto err; 132*0Sstevel@tonic-gate if (to->pkey.dsa->p != NULL) BN_free(to->pkey.dsa->p); 133*0Sstevel@tonic-gate to->pkey.dsa->p=a; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate if ((a=BN_dup(from->pkey.dsa->q)) == NULL) goto err; 136*0Sstevel@tonic-gate if (to->pkey.dsa->q != NULL) BN_free(to->pkey.dsa->q); 137*0Sstevel@tonic-gate to->pkey.dsa->q=a; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate if ((a=BN_dup(from->pkey.dsa->g)) == NULL) goto err; 140*0Sstevel@tonic-gate if (to->pkey.dsa->g != NULL) BN_free(to->pkey.dsa->g); 141*0Sstevel@tonic-gate to->pkey.dsa->g=a; 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate #endif 144*0Sstevel@tonic-gate return(1); 145*0Sstevel@tonic-gate err: 146*0Sstevel@tonic-gate return(0); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate int EVP_PKEY_missing_parameters(EVP_PKEY *pkey) 150*0Sstevel@tonic-gate { 151*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 152*0Sstevel@tonic-gate if (pkey->type == EVP_PKEY_DSA) 153*0Sstevel@tonic-gate { 154*0Sstevel@tonic-gate DSA *dsa; 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate dsa=pkey->pkey.dsa; 157*0Sstevel@tonic-gate if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) 158*0Sstevel@tonic-gate return(1); 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate #endif 161*0Sstevel@tonic-gate return(0); 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate int EVP_PKEY_cmp_parameters(EVP_PKEY *a, EVP_PKEY *b) 165*0Sstevel@tonic-gate { 166*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 167*0Sstevel@tonic-gate if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA)) 168*0Sstevel@tonic-gate { 169*0Sstevel@tonic-gate if ( BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) || 170*0Sstevel@tonic-gate BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) || 171*0Sstevel@tonic-gate BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g)) 172*0Sstevel@tonic-gate return(0); 173*0Sstevel@tonic-gate else 174*0Sstevel@tonic-gate return(1); 175*0Sstevel@tonic-gate } 176*0Sstevel@tonic-gate #endif 177*0Sstevel@tonic-gate return(-1); 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gate EVP_PKEY *EVP_PKEY_new(void) 181*0Sstevel@tonic-gate { 182*0Sstevel@tonic-gate EVP_PKEY *ret; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY)); 185*0Sstevel@tonic-gate if (ret == NULL) 186*0Sstevel@tonic-gate { 187*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE); 188*0Sstevel@tonic-gate return(NULL); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate ret->type=EVP_PKEY_NONE; 191*0Sstevel@tonic-gate ret->references=1; 192*0Sstevel@tonic-gate ret->pkey.ptr=NULL; 193*0Sstevel@tonic-gate ret->attributes=NULL; 194*0Sstevel@tonic-gate ret->save_parameters=1; 195*0Sstevel@tonic-gate return(ret); 196*0Sstevel@tonic-gate } 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gate int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key) 199*0Sstevel@tonic-gate { 200*0Sstevel@tonic-gate if (pkey == NULL) return(0); 201*0Sstevel@tonic-gate if (pkey->pkey.ptr != NULL) 202*0Sstevel@tonic-gate EVP_PKEY_free_it(pkey); 203*0Sstevel@tonic-gate pkey->type=EVP_PKEY_type(type); 204*0Sstevel@tonic-gate pkey->save_type=type; 205*0Sstevel@tonic-gate pkey->pkey.ptr=key; 206*0Sstevel@tonic-gate return(key != NULL); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 210*0Sstevel@tonic-gate int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) 211*0Sstevel@tonic-gate { 212*0Sstevel@tonic-gate int ret = EVP_PKEY_assign_RSA(pkey, key); 213*0Sstevel@tonic-gate if(ret) 214*0Sstevel@tonic-gate RSA_up_ref(key); 215*0Sstevel@tonic-gate return ret; 216*0Sstevel@tonic-gate } 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gate RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) 219*0Sstevel@tonic-gate { 220*0Sstevel@tonic-gate if(pkey->type != EVP_PKEY_RSA) { 221*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); 222*0Sstevel@tonic-gate return NULL; 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate RSA_up_ref(pkey->pkey.rsa); 225*0Sstevel@tonic-gate return pkey->pkey.rsa; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate #endif 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 230*0Sstevel@tonic-gate int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) 231*0Sstevel@tonic-gate { 232*0Sstevel@tonic-gate int ret = EVP_PKEY_assign_DSA(pkey, key); 233*0Sstevel@tonic-gate if(ret) 234*0Sstevel@tonic-gate DSA_up_ref(key); 235*0Sstevel@tonic-gate return ret; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) 239*0Sstevel@tonic-gate { 240*0Sstevel@tonic-gate if(pkey->type != EVP_PKEY_DSA) { 241*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY); 242*0Sstevel@tonic-gate return NULL; 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate DSA_up_ref(pkey->pkey.dsa); 245*0Sstevel@tonic-gate return pkey->pkey.dsa; 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate #endif 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) 252*0Sstevel@tonic-gate { 253*0Sstevel@tonic-gate int ret = EVP_PKEY_assign_DH(pkey, key); 254*0Sstevel@tonic-gate if(ret) 255*0Sstevel@tonic-gate DH_up_ref(key); 256*0Sstevel@tonic-gate return ret; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) 260*0Sstevel@tonic-gate { 261*0Sstevel@tonic-gate if(pkey->type != EVP_PKEY_DH) { 262*0Sstevel@tonic-gate EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); 263*0Sstevel@tonic-gate return NULL; 264*0Sstevel@tonic-gate } 265*0Sstevel@tonic-gate DH_up_ref(pkey->pkey.dh); 266*0Sstevel@tonic-gate return pkey->pkey.dh; 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate #endif 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate int EVP_PKEY_type(int type) 271*0Sstevel@tonic-gate { 272*0Sstevel@tonic-gate switch (type) 273*0Sstevel@tonic-gate { 274*0Sstevel@tonic-gate case EVP_PKEY_RSA: 275*0Sstevel@tonic-gate case EVP_PKEY_RSA2: 276*0Sstevel@tonic-gate return(EVP_PKEY_RSA); 277*0Sstevel@tonic-gate case EVP_PKEY_DSA: 278*0Sstevel@tonic-gate case EVP_PKEY_DSA1: 279*0Sstevel@tonic-gate case EVP_PKEY_DSA2: 280*0Sstevel@tonic-gate case EVP_PKEY_DSA3: 281*0Sstevel@tonic-gate case EVP_PKEY_DSA4: 282*0Sstevel@tonic-gate return(EVP_PKEY_DSA); 283*0Sstevel@tonic-gate case EVP_PKEY_DH: 284*0Sstevel@tonic-gate return(EVP_PKEY_DH); 285*0Sstevel@tonic-gate default: 286*0Sstevel@tonic-gate return(NID_undef); 287*0Sstevel@tonic-gate } 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate void EVP_PKEY_free(EVP_PKEY *x) 291*0Sstevel@tonic-gate { 292*0Sstevel@tonic-gate int i; 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate if (x == NULL) return; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY); 297*0Sstevel@tonic-gate #ifdef REF_PRINT 298*0Sstevel@tonic-gate REF_PRINT("EVP_PKEY",x); 299*0Sstevel@tonic-gate #endif 300*0Sstevel@tonic-gate if (i > 0) return; 301*0Sstevel@tonic-gate #ifdef REF_CHECK 302*0Sstevel@tonic-gate if (i < 0) 303*0Sstevel@tonic-gate { 304*0Sstevel@tonic-gate fprintf(stderr,"EVP_PKEY_free, bad reference count\n"); 305*0Sstevel@tonic-gate abort(); 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate #endif 308*0Sstevel@tonic-gate EVP_PKEY_free_it(x); 309*0Sstevel@tonic-gate OPENSSL_free(x); 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate static void EVP_PKEY_free_it(EVP_PKEY *x) 313*0Sstevel@tonic-gate { 314*0Sstevel@tonic-gate switch (x->type) 315*0Sstevel@tonic-gate { 316*0Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA 317*0Sstevel@tonic-gate case EVP_PKEY_RSA: 318*0Sstevel@tonic-gate case EVP_PKEY_RSA2: 319*0Sstevel@tonic-gate RSA_free(x->pkey.rsa); 320*0Sstevel@tonic-gate break; 321*0Sstevel@tonic-gate #endif 322*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA 323*0Sstevel@tonic-gate case EVP_PKEY_DSA: 324*0Sstevel@tonic-gate case EVP_PKEY_DSA2: 325*0Sstevel@tonic-gate case EVP_PKEY_DSA3: 326*0Sstevel@tonic-gate case EVP_PKEY_DSA4: 327*0Sstevel@tonic-gate DSA_free(x->pkey.dsa); 328*0Sstevel@tonic-gate break; 329*0Sstevel@tonic-gate #endif 330*0Sstevel@tonic-gate #ifndef OPENSSL_NO_DH 331*0Sstevel@tonic-gate case EVP_PKEY_DH: 332*0Sstevel@tonic-gate DH_free(x->pkey.dh); 333*0Sstevel@tonic-gate break; 334*0Sstevel@tonic-gate #endif 335*0Sstevel@tonic-gate } 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate 338