1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/crypto/signature_verifier.h" 6 7 #include <stdlib.h> 8 9 #include "base/crypto/cssm_init.h" 10 #include "base/logging.h" 11 12 namespace base { 13 14 SignatureVerifier::SignatureVerifier() : csp_handle_(0), sig_handle_(0) { 15 EnsureCSSMInit(); 16 17 static CSSM_VERSION version = {2, 0}; 18 CSSM_RETURN crtn; 19 crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &kCssmMemoryFunctions, 0, 20 CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, 21 NULL, 0, NULL, &csp_handle_); 22 DCHECK(crtn == CSSM_OK); 23 } 24 25 SignatureVerifier::~SignatureVerifier() { 26 Reset(); 27 if (csp_handle_) { 28 CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); 29 DCHECK(crtn == CSSM_OK); 30 } 31 } 32 33 bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, 34 int signature_algorithm_len, 35 const uint8* signature, 36 int signature_len, 37 const uint8* public_key_info, 38 int public_key_info_len) { 39 signature_.assign(signature, signature + signature_len); 40 public_key_info_.assign(public_key_info, 41 public_key_info + public_key_info_len); 42 43 CSSM_ALGORITHMS key_alg = CSSM_ALGID_RSA; // TODO(wtc): hardcoded. 44 45 memset(&public_key_, 0, sizeof(public_key_)); 46 public_key_.KeyData.Data = const_cast<uint8*>(&public_key_info_[0]); 47 public_key_.KeyData.Length = public_key_info_.size(); 48 public_key_.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; 49 public_key_.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; 50 public_key_.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_X509; 51 public_key_.KeyHeader.AlgorithmId = key_alg; 52 public_key_.KeyHeader.KeyClass = CSSM_KEYCLASS_PUBLIC_KEY; 53 public_key_.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; 54 public_key_.KeyHeader.KeyUsage = CSSM_KEYUSE_VERIFY; 55 CSSM_KEY_SIZE key_size; 56 CSSM_RETURN crtn; 57 crtn = CSSM_QueryKeySizeInBits(csp_handle_, NULL, &public_key_, &key_size); 58 if (crtn) { 59 NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; 60 return false; 61 } 62 public_key_.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; 63 64 // TODO(wtc): decode signature_algorithm... 65 CSSM_ALGORITHMS sig_alg = CSSM_ALGID_SHA1WithRSA; 66 67 crtn = CSSM_CSP_CreateSignatureContext(csp_handle_, sig_alg, NULL, 68 &public_key_, &sig_handle_); 69 if (crtn) { 70 NOTREACHED(); 71 return false; 72 } 73 crtn = CSSM_VerifyDataInit(sig_handle_); 74 if (crtn) { 75 NOTREACHED(); 76 return false; 77 } 78 return true; 79 } 80 81 void SignatureVerifier::VerifyUpdate(const uint8* data_part, 82 int data_part_len) { 83 CSSM_DATA data; 84 data.Data = const_cast<uint8*>(data_part); 85 data.Length = data_part_len; 86 CSSM_RETURN crtn = CSSM_VerifyDataUpdate(sig_handle_, &data, 1); 87 DCHECK(crtn == CSSM_OK); 88 } 89 90 bool SignatureVerifier::VerifyFinal() { 91 CSSM_DATA sig; 92 sig.Data = const_cast<uint8*>(&signature_[0]); 93 sig.Length = signature_.size(); 94 CSSM_RETURN crtn = CSSM_VerifyDataFinal(sig_handle_, &sig); 95 Reset(); 96 97 // crtn is CSSMERR_CSP_VERIFY_FAILED if signature verification fails. 98 return (crtn == CSSM_OK); 99 } 100 101 void SignatureVerifier::Reset() { 102 CSSM_RETURN crtn; 103 if (sig_handle_) { 104 crtn = CSSM_DeleteContext(sig_handle_); 105 DCHECK(crtn == CSSM_OK); 106 sig_handle_ = 0; 107 } 108 signature_.clear(); 109 110 // Can't call CSSM_FreeKey on public_key_ because we constructed 111 // public_key_ manually. 112 } 113 114 } // namespace base 115 116