Home | History | Annotate | Download | only in evp
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      6  * The implementation was written so as to conform with Netscapes SSL.
      7  *
      8  * This library is free for commercial and non-commercial use as long as
      9  * the following conditions are aheared to.  The following conditions
     10  * apply to all code found in this distribution, be it the RC4, RSA,
     11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
     12  * included with this distribution is covered by the same copyright terms
     13  * except that the holder is Tim Hudson (tjh (at) cryptsoft.com).
     14  *
     15  * Copyright remains Eric Young's, and as such any Copyright notices in
     16  * the code are not to be removed.
     17  * If this package is used in a product, Eric Young should be given attribution
     18  * as the author of the parts of the library used.
     19  * This can be in the form of a textual message at program startup or
     20  * in documentation (online or textual) provided with the package.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  * 3. All advertising materials mentioning features or use of this software
     31  *    must display the following acknowledgement:
     32  *    "This product includes cryptographic software written by
     33  *     Eric Young (eay (at) cryptsoft.com)"
     34  *    The word 'cryptographic' can be left out if the rouines from the library
     35  *    being used are not cryptographic related :-).
     36  * 4. If you include any Windows specific code (or a derivative thereof) from
     37  *    the apps directory (application code) you must include an acknowledgement:
     38  *    "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
     41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     50  * SUCH DAMAGE.
     51  *
     52  * The licence and distribution terms for any publically available version or
     53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
     54  * copied and put under another distribution licence
     55  * [including the GNU Public Licence.] */
     56 
     57 #include <openssl/evp.h>
     58 
     59 #include <assert.h>
     60 
     61 #include <openssl/asn1.h>
     62 #include <openssl/err.h>
     63 #include <openssl/obj.h>
     64 #include <openssl/x509.h>
     65 
     66 #include "internal.h"
     67 
     68 
     69 int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
     70   const EVP_MD *digest;
     71   EVP_PKEY *pkey;
     72   int sign_nid, paramtype;
     73 
     74   digest = EVP_MD_CTX_md(ctx);
     75   pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
     76   if (!digest || !pkey) {
     77     OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED);
     78     return 0;
     79   }
     80 
     81   if (pkey->ameth->digest_sign_algorithm) {
     82     switch (pkey->ameth->digest_sign_algorithm(ctx, algor)) {
     83       case EVP_DIGEST_SIGN_ALGORITHM_ERROR:
     84         return 0;
     85       case EVP_DIGEST_SIGN_ALGORITHM_SUCCESS:
     86         return 1;
     87       case EVP_DIGEST_SIGN_ALGORITHM_DEFAULT:
     88         /* Use default behavior. */
     89         break;
     90       default:
     91         assert(0);
     92     }
     93   }
     94 
     95   /* Default behavior: look up the OID for the algorithm/hash pair and encode
     96    * that. */
     97   if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
     98                               pkey->ameth->pkey_id)) {
     99     OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
    100     return 0;
    101   }
    102 
    103   if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) {
    104     paramtype = V_ASN1_NULL;
    105   } else {
    106     paramtype = V_ASN1_UNDEF;
    107   }
    108 
    109   X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL);
    110   return 1;
    111 }
    112 
    113 int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
    114                                       X509_ALGOR *algor,
    115                                       EVP_PKEY *pkey) {
    116   int digest_nid, pkey_nid;
    117   const EVP_PKEY_ASN1_METHOD *ameth;
    118   const EVP_MD *digest;
    119 
    120   /* Convert signature OID into digest and public key OIDs */
    121   if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &digest_nid,
    122                            &pkey_nid)) {
    123     OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
    124     return 0;
    125   }
    126 
    127   /* Check public key OID matches public key type */
    128   ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
    129   if (ameth == NULL || ameth->pkey_id != pkey->ameth->pkey_id) {
    130     OPENSSL_PUT_ERROR(EVP, EVP_R_WRONG_PUBLIC_KEY_TYPE);
    131     return 0;
    132   }
    133 
    134   /* NID_undef signals that there are custom parameters to set. */
    135   if (digest_nid == NID_undef) {
    136     if (!pkey->ameth || !pkey->ameth->digest_verify_init_from_algorithm) {
    137       OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
    138       return 0;
    139     }
    140 
    141     return pkey->ameth->digest_verify_init_from_algorithm(ctx, algor, pkey);
    142   }
    143 
    144   /* Otherwise, initialize with the digest from the OID. */
    145   digest = EVP_get_digestbynid(digest_nid);
    146   if (digest == NULL) {
    147     OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
    148     return 0;
    149   }
    150 
    151   return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey);
    152 }
    153 
    154