LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/evp - p_lib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 78 173 45.1 %
Date: 2015-10-10 Functions: 14 31 45.2 %

          Line data    Source code
       1             : /* crypto/evp/p_lib.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : #include <stdio.h>
      60             : #include "cryptlib.h"
      61             : #include <openssl/bn.h>
      62             : #include <openssl/err.h>
      63             : #include <openssl/objects.h>
      64             : #include <openssl/evp.h>
      65             : #include <openssl/asn1_mac.h>
      66             : #include <openssl/x509.h>
      67             : #ifndef OPENSSL_NO_RSA
      68             : # include <openssl/rsa.h>
      69             : #endif
      70             : #ifndef OPENSSL_NO_DSA
      71             : # include <openssl/dsa.h>
      72             : #endif
      73             : #ifndef OPENSSL_NO_DH
      74             : # include <openssl/dh.h>
      75             : #endif
      76             : 
      77             : #ifndef OPENSSL_NO_ENGINE
      78             : # include <openssl/engine.h>
      79             : #endif
      80             : 
      81             : #include "asn1_locl.h"
      82             : 
      83             : static void EVP_PKEY_free_it(EVP_PKEY *x);
      84             : 
      85         370 : int EVP_PKEY_bits(EVP_PKEY *pkey)
      86             : {
      87         370 :     if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
      88         370 :         return pkey->ameth->pkey_bits(pkey);
      89             :     return 0;
      90             : }
      91             : 
      92        2251 : int EVP_PKEY_size(EVP_PKEY *pkey)
      93             : {
      94        2251 :     if (pkey && pkey->ameth && pkey->ameth->pkey_size)
      95        2251 :         return pkey->ameth->pkey_size(pkey);
      96             :     return 0;
      97             : }
      98             : 
      99           0 : int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
     100             : {
     101             : #ifndef OPENSSL_NO_DSA
     102           0 :     if (pkey->type == EVP_PKEY_DSA) {
     103           0 :         int ret = pkey->save_parameters;
     104             : 
     105           0 :         if (mode >= 0)
     106           0 :             pkey->save_parameters = mode;
     107           0 :         return (ret);
     108             :     }
     109             : #endif
     110             : #ifndef OPENSSL_NO_EC
     111           0 :     if (pkey->type == EVP_PKEY_EC) {
     112           0 :         int ret = pkey->save_parameters;
     113             : 
     114           0 :         if (mode >= 0)
     115           0 :             pkey->save_parameters = mode;
     116           0 :         return (ret);
     117             :     }
     118             : #endif
     119             :     return (0);
     120             : }
     121             : 
     122         438 : int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
     123             : {
     124         438 :     if (to->type != from->type) {
     125           0 :         EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
     126           0 :         goto err;
     127             :     }
     128             : 
     129         438 :     if (EVP_PKEY_missing_parameters(from)) {
     130           0 :         EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
     131           0 :         goto err;
     132             :     }
     133         438 :     if (from->ameth && from->ameth->param_copy)
     134           0 :         return from->ameth->param_copy(to, from);
     135             :  err:
     136             :     return 0;
     137             : }
     138             : 
     139        1113 : int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
     140             : {
     141        1551 :     if (pkey->ameth && pkey->ameth->param_missing)
     142           0 :         return pkey->ameth->param_missing(pkey);
     143             :     return 0;
     144             : }
     145             : 
     146           0 : int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
     147             : {
     148           0 :     if (a->type != b->type)
     149             :         return -1;
     150           0 :     if (a->ameth && a->ameth->param_cmp)
     151           0 :         return a->ameth->param_cmp(a, b);
     152             :     return -2;
     153             : }
     154             : 
     155         876 : int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
     156             : {
     157         876 :     if (a->type != b->type)
     158             :         return -1;
     159             : 
     160         876 :     if (a->ameth) {
     161             :         int ret;
     162             :         /* Compare parameters if the algorithm has them */
     163         876 :         if (a->ameth->param_cmp) {
     164           0 :             ret = a->ameth->param_cmp(a, b);
     165           0 :             if (ret <= 0)
     166             :                 return ret;
     167             :         }
     168             : 
     169         876 :         if (a->ameth->pub_cmp)
     170         876 :             return a->ameth->pub_cmp(a, b);
     171             :     }
     172             : 
     173             :     return -2;
     174             : }
     175             : 
     176        5277 : EVP_PKEY *EVP_PKEY_new(void)
     177             : {
     178             :     EVP_PKEY *ret;
     179             : 
     180        5277 :     ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
     181        5277 :     if (ret == NULL) {
     182           0 :         EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
     183           0 :         return (NULL);
     184             :     }
     185        5277 :     ret->type = EVP_PKEY_NONE;
     186        5277 :     ret->save_type = EVP_PKEY_NONE;
     187        5277 :     ret->references = 1;
     188        5277 :     ret->ameth = NULL;
     189        5277 :     ret->engine = NULL;
     190        5277 :     ret->pkey.ptr = NULL;
     191        5277 :     ret->attributes = NULL;
     192        5277 :     ret->save_parameters = 1;
     193        5277 :     return (ret);
     194             : }
     195             : 
     196             : /*
     197             :  * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
     198             :  * is NULL just return 1 or 0 if the algorithm exists.
     199             :  */
     200             : 
     201        6866 : static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
     202             : {
     203             :     const EVP_PKEY_ASN1_METHOD *ameth;
     204        6866 :     ENGINE *e = NULL;
     205        6866 :     if (pkey) {
     206        6866 :         if (pkey->pkey.ptr)
     207           0 :             EVP_PKEY_free_it(pkey);
     208             :         /*
     209             :          * If key type matches and a method exists then this lookup has
     210             :          * succeeded once so just indicate success.
     211             :          */
     212        6866 :         if ((type == pkey->save_type) && pkey->ameth)
     213             :             return 1;
     214             : #ifndef OPENSSL_NO_ENGINE
     215             :         /* If we have an ENGINE release it */
     216        5277 :         if (pkey->engine) {
     217           0 :             ENGINE_finish(pkey->engine);
     218           0 :             pkey->engine = NULL;
     219             :         }
     220             : #endif
     221             :     }
     222        5277 :     if (str)
     223           0 :         ameth = EVP_PKEY_asn1_find_str(&e, str, len);
     224             :     else
     225        5277 :         ameth = EVP_PKEY_asn1_find(&e, type);
     226             : #ifndef OPENSSL_NO_ENGINE
     227        5277 :     if (!pkey && e)
     228           0 :         ENGINE_finish(e);
     229             : #endif
     230        5277 :     if (!ameth) {
     231           0 :         EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
     232           0 :         return 0;
     233             :     }
     234        5277 :     if (pkey) {
     235        5277 :         pkey->ameth = ameth;
     236        5277 :         pkey->engine = e;
     237             : 
     238        5277 :         pkey->type = pkey->ameth->pkey_id;
     239        5277 :         pkey->save_type = type;
     240             :     }
     241             :     return 1;
     242             : }
     243             : 
     244        1589 : int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
     245             : {
     246        6866 :     return pkey_set_type(pkey, type, NULL, -1);
     247             : }
     248             : 
     249           0 : int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
     250             : {
     251           0 :     return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
     252             : }
     253             : 
     254        5264 : int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
     255             : {
     256        5277 :     if (!EVP_PKEY_set_type(pkey, type))
     257             :         return 0;
     258        5277 :     pkey->pkey.ptr = key;
     259        5277 :     return (key != NULL);
     260             : }
     261             : 
     262           0 : void *EVP_PKEY_get0(EVP_PKEY *pkey)
     263             : {
     264           0 :     return pkey->pkey.ptr;
     265             : }
     266             : 
     267             : #ifndef OPENSSL_NO_RSA
     268          13 : int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
     269             : {
     270             :     int ret = EVP_PKEY_assign_RSA(pkey, key);
     271          13 :     if (ret)
     272          13 :         RSA_up_ref(key);
     273          13 :     return ret;
     274             : }
     275             : 
     276          12 : RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
     277             : {
     278          12 :     if (pkey->type != EVP_PKEY_RSA) {
     279           0 :         EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
     280           0 :         return NULL;
     281             :     }
     282          12 :     RSA_up_ref(pkey->pkey.rsa);
     283          12 :     return pkey->pkey.rsa;
     284             : }
     285             : #endif
     286             : 
     287             : #ifndef OPENSSL_NO_DSA
     288           0 : int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
     289             : {
     290             :     int ret = EVP_PKEY_assign_DSA(pkey, key);
     291           0 :     if (ret)
     292           0 :         DSA_up_ref(key);
     293           0 :     return ret;
     294             : }
     295             : 
     296           0 : DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
     297             : {
     298           0 :     if (pkey->type != EVP_PKEY_DSA) {
     299           0 :         EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
     300           0 :         return NULL;
     301             :     }
     302           0 :     DSA_up_ref(pkey->pkey.dsa);
     303           0 :     return pkey->pkey.dsa;
     304             : }
     305             : #endif
     306             : 
     307             : #ifndef OPENSSL_NO_EC
     308             : 
     309           0 : int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
     310             : {
     311             :     int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
     312           0 :     if (ret)
     313           0 :         EC_KEY_up_ref(key);
     314           0 :     return ret;
     315             : }
     316             : 
     317           0 : EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
     318             : {
     319           0 :     if (pkey->type != EVP_PKEY_EC) {
     320           0 :         EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
     321           0 :         return NULL;
     322             :     }
     323           0 :     EC_KEY_up_ref(pkey->pkey.ec);
     324           0 :     return pkey->pkey.ec;
     325             : }
     326             : #endif
     327             : 
     328             : #ifndef OPENSSL_NO_DH
     329             : 
     330           0 : int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
     331             : {
     332             :     int ret = EVP_PKEY_assign_DH(pkey, key);
     333           0 :     if (ret)
     334           0 :         DH_up_ref(key);
     335           0 :     return ret;
     336             : }
     337             : 
     338           0 : DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
     339             : {
     340           0 :     if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
     341           0 :         EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
     342           0 :         return NULL;
     343             :     }
     344           0 :     DH_up_ref(pkey->pkey.dh);
     345           0 :     return pkey->pkey.dh;
     346             : }
     347             : #endif
     348             : 
     349         370 : int EVP_PKEY_type(int type)
     350             : {
     351             :     int ret;
     352             :     const EVP_PKEY_ASN1_METHOD *ameth;
     353             :     ENGINE *e;
     354         370 :     ameth = EVP_PKEY_asn1_find(&e, type);
     355         370 :     if (ameth)
     356         370 :         ret = ameth->pkey_id;
     357             :     else
     358             :         ret = NID_undef;
     359             : #ifndef OPENSSL_NO_ENGINE
     360         370 :     if (e)
     361           0 :         ENGINE_finish(e);
     362             : #endif
     363         370 :     return ret;
     364             : }
     365             : 
     366           0 : int EVP_PKEY_id(const EVP_PKEY *pkey)
     367             : {
     368           0 :     return pkey->type;
     369             : }
     370             : 
     371           0 : int EVP_PKEY_base_id(const EVP_PKEY *pkey)
     372             : {
     373           0 :     return EVP_PKEY_type(pkey->type);
     374             : }
     375             : 
     376       37869 : void EVP_PKEY_free(EVP_PKEY *x)
     377             : {
     378             :     int i;
     379             : 
     380       37869 :     if (x == NULL)
     381             :         return;
     382             : 
     383       36223 :     i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY);
     384             : #ifdef REF_PRINT
     385             :     REF_PRINT("EVP_PKEY", x);
     386             : #endif
     387       36223 :     if (i > 0)
     388             :         return;
     389             : #ifdef REF_CHECK
     390             :     if (i < 0) {
     391             :         fprintf(stderr, "EVP_PKEY_free, bad reference count\n");
     392             :         abort();
     393             :     }
     394             : #endif
     395        5277 :     EVP_PKEY_free_it(x);
     396        5277 :     if (x->attributes)
     397           0 :         sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
     398        5277 :     OPENSSL_free(x);
     399             : }
     400             : 
     401        5277 : static void EVP_PKEY_free_it(EVP_PKEY *x)
     402             : {
     403        5277 :     if (x->ameth && x->ameth->pkey_free) {
     404        5277 :         x->ameth->pkey_free(x);
     405        5277 :         x->pkey.ptr = NULL;
     406             :     }
     407             : #ifndef OPENSSL_NO_ENGINE
     408        5277 :     if (x->engine) {
     409           0 :         ENGINE_finish(x->engine);
     410           0 :         x->engine = NULL;
     411             :     }
     412             : #endif
     413        5277 : }
     414             : 
     415           0 : static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
     416             :                      const char *kstr)
     417             : {
     418           0 :     BIO_indent(out, indent, 128);
     419           0 :     BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
     420             :                kstr, OBJ_nid2ln(pkey->type));
     421           0 :     return 1;
     422             : }
     423             : 
     424           0 : int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
     425             :                           int indent, ASN1_PCTX *pctx)
     426             : {
     427           0 :     if (pkey->ameth && pkey->ameth->pub_print)
     428           0 :         return pkey->ameth->pub_print(out, pkey, indent, pctx);
     429             : 
     430           0 :     return unsup_alg(out, pkey, indent, "Public Key");
     431             : }
     432             : 
     433           0 : int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
     434             :                            int indent, ASN1_PCTX *pctx)
     435             : {
     436           0 :     if (pkey->ameth && pkey->ameth->priv_print)
     437           0 :         return pkey->ameth->priv_print(out, pkey, indent, pctx);
     438             : 
     439           0 :     return unsup_alg(out, pkey, indent, "Private Key");
     440             : }
     441             : 
     442           0 : int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
     443             :                           int indent, ASN1_PCTX *pctx)
     444             : {
     445           0 :     if (pkey->ameth && pkey->ameth->param_print)
     446           0 :         return pkey->ameth->param_print(out, pkey, indent, pctx);
     447           0 :     return unsup_alg(out, pkey, indent, "Parameters");
     448             : }
     449             : 
     450           0 : int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
     451             : {
     452           0 :     if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
     453             :         return -2;
     454           0 :     return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID,
     455             :                                   0, pnid);
     456             : }

Generated by: LCOV version 1.10