1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/rsa_private_key.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <list> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Helper for error handling during key import. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define READ_ASSERT(truth) \ 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(truth)) { \ 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); \ 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; \ 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto { 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottRSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!result->InitProvider()) 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD flags = CRYPT_EXPORTABLE; 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The size is encoded as the upper 16 bits of the flags. :: sigh ::. 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott flags |= (num_bits << 16); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!CryptGenKey(result->provider_, CALG_RSA_SIGN, flags, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch result->key_.receive())) 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result.release(); 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::CreateSensitive(uint16 num_bits) { 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTIMPLEMENTED(); 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottRSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::vector<uint8>& input) { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!result->InitProvider()) 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PrivateKeyInfoCodec pki(false); // Little-Endian 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.Import(input); 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int blob_size = sizeof(PUBLICKEYSTRUC) + 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sizeof(RSAPUBKEY) + 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.modulus()->size() + 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.prime1()->size() + 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.prime2()->size() + 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.exponent1()->size() + 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.exponent2()->size() + 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.coefficient()->size() + 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.private_exponent()->size(); 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<BYTE> blob(new BYTE[blob_size]); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint8* dest = blob.get(); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PUBLICKEYSTRUC* public_key_struc = reinterpret_cast<PUBLICKEYSTRUC*>(dest); 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_key_struc->bType = PRIVATEKEYBLOB; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_key_struc->bVersion = 0x02; 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_key_struc->reserved = 0; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_key_struc->aiKeyAlg = CALG_RSA_SIGN; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += sizeof(PUBLICKEYSTRUC); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RSAPUBKEY* rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(dest); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rsa_pub_key->magic = 0x32415352; 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rsa_pub_key->bitlen = pki.modulus()->size() * 8; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int public_exponent_int = 0; 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = pki.public_exponent()->size(); i > 0; --i) { 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_exponent_int <<= 8; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public_exponent_int |= (*pki.public_exponent())[i - 1]; 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott rsa_pub_key->pubexp = public_exponent_int; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += sizeof(RSAPUBKEY); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.modulus()->front(), pki.modulus()->size()); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.modulus()->size(); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.prime1()->front(), pki.prime1()->size()); 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.prime1()->size(); 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.prime2()->front(), pki.prime2()->size()); 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.prime2()->size(); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.exponent1()->front(), pki.exponent1()->size()); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.exponent1()->size(); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.exponent2()->front(), pki.exponent2()->size()); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.exponent2()->size(); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(dest, &pki.coefficient()->front(), pki.coefficient()->size()); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.coefficient()->size(); 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick memcpy(dest, &pki.private_exponent()->front(), 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick pki.private_exponent()->size()); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott dest += pki.private_exponent()->size(); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott READ_ASSERT(dest == blob.get() + blob_size); 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!CryptImportKey(result->provider_, 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick reinterpret_cast<uint8*>(public_key_struc), blob_size, 0, 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CRYPT_EXPORTABLE, result->key_.receive())) 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result.release(); 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo( 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::vector<uint8>& input) { 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTIMPLEMENTED(); 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickRSAPrivateKey* RSAPrivateKey::FindFromPublicKeyInfo( 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::vector<uint8>& input) { 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTIMPLEMENTED(); 1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottRSAPrivateKey::RSAPrivateKey() : provider_(NULL), key_(NULL) {} 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRSAPrivateKey::~RSAPrivateKey() {} 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RSAPrivateKey::InitProvider() { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return FALSE != CryptAcquireContext(provider_.receive(), NULL, NULL, 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Export the key 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD blob_length = 0; 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, NULL, &blob_length)) { 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<uint8> blob(new uint8[blob_length]); 144731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!CryptExportKey(key_, 0, PRIVATEKEYBLOB, 0, blob.get(), &blob_length)) { 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott uint8* pos = blob.get(); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PUBLICKEYSTRUC *publickey_struct = reinterpret_cast<PUBLICKEYSTRUC*>(pos); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += sizeof(PUBLICKEYSTRUC); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RSAPUBKEY *rsa_pub_key = reinterpret_cast<RSAPUBKEY*>(pos); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += sizeof(RSAPUBKEY); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int mod_size = rsa_pub_key->bitlen / 8; 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int primes_size = rsa_pub_key->bitlen / 16; 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott PrivateKeyInfoCodec pki(false); // Little-Endian 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.modulus()->assign(pos, pos + mod_size); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += mod_size; 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.prime1()->assign(pos, pos + primes_size); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += primes_size; 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.prime2()->assign(pos, pos + primes_size); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += primes_size; 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.exponent1()->assign(pos, pos + primes_size); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += primes_size; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.exponent2()->assign(pos, pos + primes_size); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += primes_size; 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.coefficient()->assign(pos, pos + primes_size); 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += primes_size; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.private_exponent()->assign(pos, pos + mod_size); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pos += mod_size; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pki.public_exponent()->assign(reinterpret_cast<uint8*>(&rsa_pub_key->pubexp), 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<uint8*>(&rsa_pub_key->pubexp) + 4); 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK_EQ(pos - blob_length, reinterpret_cast<BYTE*>(publickey_struct)); 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return pki.Export(output); 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD key_info_len; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CryptExportPublicKeyInfo( 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NULL, &key_info_len)) { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<uint8> key_info(new uint8[key_info_len]); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CryptExportPublicKeyInfo( 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott provider_, AT_SIGNATURE, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), &key_info_len)) { 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD encoded_length; 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CryptEncodeObject( 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), NULL, 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &encoded_length)) { 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<BYTE> encoded(new BYTE[encoded_length]); 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CryptEncodeObject( 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_PUBLIC_KEY_INFO, 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<CERT_PUBLIC_KEY_INFO*>(key_info.get()), encoded.get(), 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &encoded_length)) { 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < encoded_length; ++i) 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->push_back(encoded[i]); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace crypto 230