LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/asn1 - x_pubkey.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 28 149 18.8 %
Date: 2015-10-10 Functions: 3 17 17.6 %

          Line data    Source code
       1             : /* crypto/asn1/x_pubkey.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/asn1t.h>
      62             : #include <openssl/x509.h>
      63             : #include "asn1_locl.h"
      64             : #ifndef OPENSSL_NO_RSA
      65             : # include <openssl/rsa.h>
      66             : #endif
      67             : #ifndef OPENSSL_NO_DSA
      68             : # include <openssl/dsa.h>
      69             : #endif
      70             : 
      71             : /* Minor tweak to operation: free up EVP_PKEY */
      72       10086 : static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
      73             :                      void *exarg)
      74             : {
      75       10086 :     if (operation == ASN1_OP_FREE_POST) {
      76        1681 :         X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
      77        1681 :         EVP_PKEY_free(pubkey->pkey);
      78             :     }
      79       10086 :     return 1;
      80             : }
      81             : 
      82             : ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
      83             :         ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
      84             :         ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
      85             : } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
      86             : 
      87           0 : IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
      88             : 
      89           0 : int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
      90             : {
      91             :     X509_PUBKEY *pk = NULL;
      92             : 
      93           0 :     if (x == NULL)
      94             :         return (0);
      95             : 
      96           0 :     if ((pk = X509_PUBKEY_new()) == NULL)
      97             :         goto error;
      98             : 
      99           0 :     if (pkey->ameth) {
     100           0 :         if (pkey->ameth->pub_encode) {
     101           0 :             if (!pkey->ameth->pub_encode(pk, pkey)) {
     102           0 :                 X509err(X509_F_X509_PUBKEY_SET,
     103             :                         X509_R_PUBLIC_KEY_ENCODE_ERROR);
     104           0 :                 goto error;
     105             :             }
     106             :         } else {
     107           0 :             X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
     108           0 :             goto error;
     109             :         }
     110             :     } else {
     111           0 :         X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
     112           0 :         goto error;
     113             :     }
     114             : 
     115           0 :     if (*x != NULL)
     116             :         X509_PUBKEY_free(*x);
     117             : 
     118           0 :     *x = pk;
     119             : 
     120           0 :     return 1;
     121             :  error:
     122           0 :     if (pk != NULL)
     123             :         X509_PUBKEY_free(pk);
     124             :     return 0;
     125             : }
     126             : 
     127        4349 : EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
     128             : {
     129             :     EVP_PKEY *ret = NULL;
     130             : 
     131        4349 :     if (key == NULL)
     132             :         goto error;
     133             : 
     134        4349 :     if (key->pkey != NULL) {
     135        3210 :         CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
     136        3210 :         return key->pkey;
     137             :     }
     138             : 
     139        1139 :     if (key->public_key == NULL)
     140             :         goto error;
     141             : 
     142        1139 :     if ((ret = EVP_PKEY_new()) == NULL) {
     143           0 :         X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
     144           0 :         goto error;
     145             :     }
     146             : 
     147        1139 :     if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
     148           0 :         X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
     149           0 :         goto error;
     150             :     }
     151             : 
     152        1139 :     if (ret->ameth->pub_decode) {
     153        1139 :         if (!ret->ameth->pub_decode(ret, key)) {
     154           0 :             X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
     155           0 :             goto error;
     156             :         }
     157             :     } else {
     158           0 :         X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
     159           0 :         goto error;
     160             :     }
     161             : 
     162             :     /* Check to see if another thread set key->pkey first */
     163        1139 :     CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
     164        1139 :     if (key->pkey) {
     165           0 :         CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
     166           0 :         EVP_PKEY_free(ret);
     167           0 :         ret = key->pkey;
     168             :     } else {
     169        1139 :         key->pkey = ret;
     170        1139 :         CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
     171             :     }
     172        1139 :     CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
     173             : 
     174        1139 :     return ret;
     175             : 
     176             :  error:
     177           0 :     if (ret != NULL)
     178           0 :         EVP_PKEY_free(ret);
     179             :     return (NULL);
     180             : }
     181             : 
     182             : /*
     183             :  * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
     184             :  * decode as X509_PUBKEY
     185             :  */
     186             : 
     187           0 : EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
     188             : {
     189             :     X509_PUBKEY *xpk;
     190             :     EVP_PKEY *pktmp;
     191             :     xpk = d2i_X509_PUBKEY(NULL, pp, length);
     192           0 :     if (!xpk)
     193             :         return NULL;
     194           0 :     pktmp = X509_PUBKEY_get(xpk);
     195             :     X509_PUBKEY_free(xpk);
     196           0 :     if (!pktmp)
     197             :         return NULL;
     198           0 :     if (a) {
     199           0 :         EVP_PKEY_free(*a);
     200           0 :         *a = pktmp;
     201             :     }
     202           0 :     return pktmp;
     203             : }
     204             : 
     205           0 : int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
     206             : {
     207           0 :     X509_PUBKEY *xpk = NULL;
     208             :     int ret;
     209           0 :     if (!a)
     210             :         return 0;
     211           0 :     if (!X509_PUBKEY_set(&xpk, a))
     212             :         return 0;
     213           0 :     ret = i2d_X509_PUBKEY(xpk, pp);
     214           0 :     X509_PUBKEY_free(xpk);
     215           0 :     return ret;
     216             : }
     217             : 
     218             : /*
     219             :  * The following are equivalents but which return RSA and DSA keys
     220             :  */
     221             : #ifndef OPENSSL_NO_RSA
     222           0 : RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
     223             : {
     224             :     EVP_PKEY *pkey;
     225             :     RSA *key;
     226             :     const unsigned char *q;
     227           0 :     q = *pp;
     228           0 :     pkey = d2i_PUBKEY(NULL, &q, length);
     229           0 :     if (!pkey)
     230             :         return NULL;
     231           0 :     key = EVP_PKEY_get1_RSA(pkey);
     232           0 :     EVP_PKEY_free(pkey);
     233           0 :     if (!key)
     234             :         return NULL;
     235           0 :     *pp = q;
     236           0 :     if (a) {
     237           0 :         RSA_free(*a);
     238           0 :         *a = key;
     239             :     }
     240           0 :     return key;
     241             : }
     242             : 
     243           0 : int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
     244             : {
     245             :     EVP_PKEY *pktmp;
     246             :     int ret;
     247           0 :     if (!a)
     248             :         return 0;
     249           0 :     pktmp = EVP_PKEY_new();
     250           0 :     if (!pktmp) {
     251           0 :         ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
     252           0 :         return 0;
     253             :     }
     254           0 :     EVP_PKEY_set1_RSA(pktmp, a);
     255           0 :     ret = i2d_PUBKEY(pktmp, pp);
     256           0 :     EVP_PKEY_free(pktmp);
     257           0 :     return ret;
     258             : }
     259             : #endif
     260             : 
     261             : #ifndef OPENSSL_NO_DSA
     262           0 : DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
     263             : {
     264             :     EVP_PKEY *pkey;
     265             :     DSA *key;
     266             :     const unsigned char *q;
     267           0 :     q = *pp;
     268           0 :     pkey = d2i_PUBKEY(NULL, &q, length);
     269           0 :     if (!pkey)
     270             :         return NULL;
     271           0 :     key = EVP_PKEY_get1_DSA(pkey);
     272           0 :     EVP_PKEY_free(pkey);
     273           0 :     if (!key)
     274             :         return NULL;
     275           0 :     *pp = q;
     276           0 :     if (a) {
     277           0 :         DSA_free(*a);
     278           0 :         *a = key;
     279             :     }
     280           0 :     return key;
     281             : }
     282             : 
     283           0 : int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
     284             : {
     285             :     EVP_PKEY *pktmp;
     286             :     int ret;
     287           0 :     if (!a)
     288             :         return 0;
     289           0 :     pktmp = EVP_PKEY_new();
     290           0 :     if (!pktmp) {
     291           0 :         ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
     292           0 :         return 0;
     293             :     }
     294           0 :     EVP_PKEY_set1_DSA(pktmp, a);
     295           0 :     ret = i2d_PUBKEY(pktmp, pp);
     296           0 :     EVP_PKEY_free(pktmp);
     297           0 :     return ret;
     298             : }
     299             : #endif
     300             : 
     301             : #ifndef OPENSSL_NO_EC
     302           0 : EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
     303             : {
     304             :     EVP_PKEY *pkey;
     305             :     EC_KEY *key;
     306             :     const unsigned char *q;
     307           0 :     q = *pp;
     308           0 :     pkey = d2i_PUBKEY(NULL, &q, length);
     309           0 :     if (!pkey)
     310             :         return (NULL);
     311           0 :     key = EVP_PKEY_get1_EC_KEY(pkey);
     312           0 :     EVP_PKEY_free(pkey);
     313           0 :     if (!key)
     314             :         return (NULL);
     315           0 :     *pp = q;
     316           0 :     if (a) {
     317           0 :         EC_KEY_free(*a);
     318           0 :         *a = key;
     319             :     }
     320           0 :     return (key);
     321             : }
     322             : 
     323           0 : int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
     324             : {
     325             :     EVP_PKEY *pktmp;
     326             :     int ret;
     327           0 :     if (!a)
     328             :         return (0);
     329           0 :     if ((pktmp = EVP_PKEY_new()) == NULL) {
     330           0 :         ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
     331           0 :         return (0);
     332             :     }
     333           0 :     EVP_PKEY_set1_EC_KEY(pktmp, a);
     334           0 :     ret = i2d_PUBKEY(pktmp, pp);
     335           0 :     EVP_PKEY_free(pktmp);
     336           0 :     return (ret);
     337             : }
     338             : #endif
     339             : 
     340           0 : int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
     341             :                            int ptype, void *pval,
     342             :                            unsigned char *penc, int penclen)
     343             : {
     344           0 :     if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
     345             :         return 0;
     346           0 :     if (penc) {
     347           0 :         if (pub->public_key->data)
     348           0 :             OPENSSL_free(pub->public_key->data);
     349           0 :         pub->public_key->data = penc;
     350           0 :         pub->public_key->length = penclen;
     351             :         /* Set number of unused bits to zero */
     352           0 :         pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
     353           0 :         pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
     354             :     }
     355             :     return 1;
     356             : }
     357             : 
     358        1139 : int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
     359             :                            const unsigned char **pk, int *ppklen,
     360             :                            X509_ALGOR **pa, X509_PUBKEY *pub)
     361             : {
     362        1139 :     if (ppkalg)
     363           0 :         *ppkalg = pub->algor->algorithm;
     364        1139 :     if (pk) {
     365        1139 :         *pk = pub->public_key->data;
     366        1139 :         *ppklen = pub->public_key->length;
     367             :     }
     368        1139 :     if (pa)
     369           0 :         *pa = pub->algor;
     370        1139 :     return 1;
     371             : }

Generated by: LCOV version 1.10