polochallengeresponse.cc revision 7c9978567a202d6aa98beac5da5e1b3b34792862
1// Copyright 2012 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15// This class performs several computations on the client and server public keys 16// to generate and verify challenge hashes. 17 18#include "polo/pairing/polochallengeresponse.h" 19 20#include <glog/logging.h> 21#include "polo/util/poloutil.h" 22 23namespace polo { 24namespace pairing { 25 26PoloChallengeResponse::PoloChallengeResponse(X509* client_cert, 27 X509* server_cert) 28 : client_cert(client_cert), 29 server_cert(server_cert) { 30} 31 32Alpha* PoloChallengeResponse::GetAlpha(const Nonce& nonce) const { 33 EVP_PKEY* client_pkey = X509_get_pubkey(client_cert); 34 if (!client_pkey) { 35 return NULL; 36 } 37 38 RSA* client_pub_rsa = EVP_PKEY_get1_RSA(client_pkey); 39 if (!client_pub_rsa) { 40 return NULL; 41 } 42 43 EVP_PKEY* server_pkey = X509_get_pubkey(server_cert); 44 if (!server_pkey) { 45 return NULL; 46 } 47 48 RSA* server_pub_rsa = EVP_PKEY_get1_RSA(server_pkey); 49 if (!server_pub_rsa) { 50 return NULL; 51 } 52 53 // Compute a hash of the concatenated public keys. The client and server 54 // modulus and exponent are concatenated along with the random nonce then a 55 // SHA256 hash is computed on the result. 56 size_t client_modulus_size = BN_num_bytes(client_pub_rsa->n); 57 size_t client_exponent_size = BN_num_bytes(client_pub_rsa->e); 58 59 size_t server_modulus_size = BN_num_bytes(server_pub_rsa->n); 60 size_t server_exponent_size = BN_num_bytes(server_pub_rsa->e); 61 62 size_t buffer_size = client_modulus_size + client_exponent_size 63 + server_modulus_size + server_exponent_size 64 + nonce.size(); 65 66 uint8_t* buffer = new unsigned char[buffer_size]; 67 uint8_t* pos = buffer; 68 69 BN_bn2bin(client_pub_rsa->n, pos); 70 pos += client_modulus_size; 71 72 BN_bn2bin(client_pub_rsa->e, pos); 73 pos += client_exponent_size; 74 75 BN_bn2bin(server_pub_rsa->n, pos); 76 pos += server_modulus_size; 77 78 BN_bn2bin(server_pub_rsa->e, pos); 79 pos += server_exponent_size; 80 81 memcpy(pos, &nonce[0], nonce.size()); 82 83 Alpha* alpha = new Alpha(SHA256_DIGEST_LENGTH); 84 SHA256(buffer, buffer_size, &(*alpha)[0]); 85 delete[] buffer; 86 87 RSA_free(client_pub_rsa); 88 EVP_PKEY_free(client_pkey); 89 90 RSA_free(server_pub_rsa); 91 EVP_PKEY_free(server_pkey); 92 93 return alpha; 94} 95 96Gamma* PoloChallengeResponse::GetGamma(const Nonce& nonce) const { 97 const Alpha* alpha = GetAlpha(nonce); 98 if (!alpha) { 99 return NULL; 100 } 101 102 Gamma* gamma = new Gamma(nonce.size() * 2); 103 104 if (alpha->size() >= nonce.size()) { 105 memcpy(&(*gamma)[0], &(*alpha)[0], nonce.size()); 106 memcpy(&(*gamma)[nonce.size()], &nonce[0], nonce.size()); 107 } 108 delete alpha; 109 110 return gamma; 111} 112 113Nonce* PoloChallengeResponse::ExtractNonce(const Gamma& gamma) const { 114 if ((gamma.size() < 2) || (gamma.size() % 2 != 0)) { 115 return NULL; 116 } 117 118 Nonce* nonce = new Nonce(gamma.size() / 2); 119 memcpy(&(*nonce)[0], &gamma[nonce->size()], nonce->size()); 120 121 return nonce; 122} 123 124bool PoloChallengeResponse::CheckGamma(const Gamma& gamma) const { 125 const Nonce* nonce = ExtractNonce(gamma); 126 127 if (!nonce) { 128 return false; 129 } 130 131 const Gamma* expected = GetGamma(*nonce); 132 133 LOG(INFO) << "CheckGamma expected: " 134 << util::PoloUtil::BytesToHexString(&(*expected)[0], expected->size()) 135 << " actual: " 136 << util::PoloUtil::BytesToHexString(&gamma[0], gamma.size()); 137 138 bool check = (gamma == (*expected)); 139 140 delete nonce; 141 delete expected; 142 143 return check; 144} 145 146} // namespace pairing 147} // namespace polo 148