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