Home | History | Annotate | Download | only in src
      1 /*############################################################################
      2   # Copyright 2016-2017 Intel Corporation
      3   #
      4   # Licensed under the Apache License, Version 2.0 (the "License");
      5   # you may not use this file except in compliance with the License.
      6   # You may obtain a copy of the License at
      7   #
      8   #     http://www.apache.org/licenses/LICENSE-2.0
      9   #
     10   # Unless required by applicable law or agreed to in writing, software
     11   # distributed under the License is distributed on an "AS IS" BASIS,
     12   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13   # See the License for the specific language governing permissions and
     14   # limitations under the License.
     15   ############################################################################*/
     16 
     17 /*!
     18  * \file
     19  * \brief Signature verification implementation.
     20  */
     21 
     22 #include "src/verifysig.h"
     23 
     24 #include <stdlib.h>
     25 
     26 #include "epid/common/file_parser.h"
     27 #include "epid/verifier/api.h"
     28 
     29 EpidStatus Verify(EpidSignature const* sig, size_t sig_len, void const* msg,
     30                   size_t msg_len, void const* basename, size_t basename_len,
     31                   void const* signed_priv_rl, size_t signed_priv_rl_size,
     32                   void const* signed_sig_rl, size_t signed_sig_rl_size,
     33                   void const* signed_grp_rl, size_t signed_grp_rl_size,
     34                   VerifierRl const* ver_rl, size_t ver_rl_size,
     35                   void const* signed_pub_key, size_t signed_pub_key_size,
     36                   EpidCaCertificate const* cacert, HashAlg hash_alg,
     37                   void** verifier_precomp, size_t* verifier_precomp_size) {
     38   EpidStatus result = kEpidErr;
     39   VerifierCtx* ctx = NULL;
     40   PrivRl* priv_rl = NULL;
     41   SigRl* sig_rl = NULL;
     42   GroupRl* grp_rl = NULL;
     43 
     44   do {
     45     GroupPubKey pub_key = {0};
     46     // authenticate and extract group public key
     47     result = EpidParseGroupPubKeyFile(signed_pub_key, signed_pub_key_size,
     48                                       cacert, &pub_key);
     49     if (kEpidNoErr != result) {
     50       break;
     51     }
     52     // ensure the pre-computation blob is not in a legacy format
     53     if (*verifier_precomp &&
     54         *verifier_precomp_size != sizeof(VerifierPrecomp)) {
     55       result = kEpidBadArgErr;
     56       break;
     57     }
     58     *verifier_precomp_size = sizeof(VerifierPrecomp);
     59 
     60     // create verifier
     61     result = EpidVerifierCreate(&pub_key, *verifier_precomp, &ctx);
     62     if (kEpidNoErr != result) {
     63       break;
     64     }
     65 
     66     // serialize verifier pre-computation blob
     67     if (!*verifier_precomp) {
     68       *verifier_precomp = calloc(1, *verifier_precomp_size);
     69     }
     70     result = EpidVerifierWritePrecomp(ctx, *verifier_precomp);
     71     if (kEpidNoErr != result) {
     72       break;
     73     }
     74 
     75     // set hash algorithm used for signing
     76     result = EpidVerifierSetHashAlg(ctx, hash_alg);
     77     if (kEpidNoErr != result) {
     78       break;
     79     }
     80 
     81     // set the basename used for signing
     82     result = EpidVerifierSetBasename(ctx, basename, basename_len);
     83     if (kEpidNoErr != result) {
     84       break;
     85     }
     86 
     87     if (signed_priv_rl) {
     88       // authenticate and determine space needed for RL
     89       size_t priv_rl_size = 0;
     90       result = EpidParsePrivRlFile(signed_priv_rl, signed_priv_rl_size, cacert,
     91                                    NULL, &priv_rl_size);
     92       if (kEpidNoErr != result) {
     93         break;
     94       }
     95 
     96       priv_rl = calloc(1, priv_rl_size);
     97       if (!priv_rl) {
     98         result = kEpidMemAllocErr;
     99         break;
    100       }
    101 
    102       // fill the rl
    103       result = EpidParsePrivRlFile(signed_priv_rl, signed_priv_rl_size, cacert,
    104                                    priv_rl, &priv_rl_size);
    105       if (kEpidNoErr != result) {
    106         break;
    107       }
    108 
    109       // set private key based revocation list
    110       result = EpidVerifierSetPrivRl(ctx, priv_rl, priv_rl_size);
    111       if (kEpidNoErr != result) {
    112         break;
    113       }
    114     }  // if (signed_priv_rl)
    115 
    116     if (signed_sig_rl) {
    117       // authenticate and determine space needed for RL
    118       size_t sig_rl_size = 0;
    119       result = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert,
    120                                   NULL, &sig_rl_size);
    121       if (kEpidNoErr != result) {
    122         break;
    123       }
    124 
    125       sig_rl = calloc(1, sig_rl_size);
    126       if (!sig_rl) {
    127         result = kEpidMemAllocErr;
    128         break;
    129       }
    130 
    131       // fill the rl
    132       result = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert,
    133                                   sig_rl, &sig_rl_size);
    134       if (kEpidNoErr != result) {
    135         break;
    136       }
    137 
    138       // set signature based revocation list
    139       result = EpidVerifierSetSigRl(ctx, sig_rl, sig_rl_size);
    140       if (kEpidNoErr != result) {
    141         break;
    142       }
    143     }  // if (signed_sig_rl)
    144 
    145     if (signed_grp_rl) {
    146       // authenticate and determine space needed for RL
    147       size_t grp_rl_size = 0;
    148       result = EpidParseGroupRlFile(signed_grp_rl, signed_grp_rl_size, cacert,
    149                                     NULL, &grp_rl_size);
    150       if (kEpidNoErr != result) {
    151         break;
    152       }
    153 
    154       grp_rl = calloc(1, grp_rl_size);
    155       if (!grp_rl) {
    156         result = kEpidMemAllocErr;
    157         break;
    158       }
    159 
    160       // fill the rl
    161       result = EpidParseGroupRlFile(signed_grp_rl, signed_grp_rl_size, cacert,
    162                                     grp_rl, &grp_rl_size);
    163       if (kEpidNoErr != result) {
    164         break;
    165       }
    166       // set group revocation list
    167       result = EpidVerifierSetGroupRl(ctx, grp_rl, grp_rl_size);
    168       if (kEpidNoErr != result) {
    169         break;
    170       }
    171     }  // if (signed_grp_rl)
    172 
    173     if (ver_rl) {
    174       // set verifier based revocation list
    175       result = EpidVerifierSetVerifierRl(ctx, ver_rl, ver_rl_size);
    176       if (kEpidNoErr != result) {
    177         break;
    178       }
    179     }
    180 
    181     // verify signature
    182     result = EpidVerify(ctx, sig, sig_len, msg, msg_len);
    183     if (kEpidNoErr != result) {
    184       break;
    185     }
    186   } while (0);
    187 
    188   // delete verifier
    189   EpidVerifierDelete(&ctx);
    190 
    191   if (priv_rl) free(priv_rl);
    192   if (sig_rl) free(sig_rl);
    193   if (grp_rl) free(grp_rl);
    194 
    195   return result;
    196 }
    197