Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(954)

Unified Diff: net/base/keygen_handler_win.cc

Issue 2536993002: Remove support for the keygen tag (Closed)
Patch Set: Rebased Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/keygen_handler_unittest.cc ('k') | net/base/net_error_list.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/keygen_handler_win.cc
diff --git a/net/base/keygen_handler_win.cc b/net/base/keygen_handler_win.cc
deleted file mode 100644
index f88e7e12579d899bd6b7c24275f06a3638a8d84a..0000000000000000000000000000000000000000
--- a/net/base/keygen_handler_win.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/base/keygen_handler.h"
-
-#include <windows.h>
-#include <rpc.h>
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "crypto/capi_util.h"
-#include "crypto/scoped_capi_types.h"
-#include "crypto/wincrypt_shim.h"
-
-namespace net {
-
-// Assigns the contents of a CERT_PUBLIC_KEY_INFO structure for the signing
-// key in |prov| to |output|. Returns true if encoding was successful.
-bool GetSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
- BOOL ok;
- DWORD size = 0;
-
- // From the private key stored in HCRYPTPROV, obtain the public key, stored
- // as a CERT_PUBLIC_KEY_INFO structure. Currently, only RSA public keys are
- // supported.
- ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- const_cast<char*>(szOID_RSA_RSA), 0, NULL,
- NULL, &size);
- DCHECK(ok);
- if (!ok)
- return false;
-
- output->resize(size);
-
- PCERT_PUBLIC_KEY_INFO public_key_casted =
- reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&(*output)[0]);
- ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- const_cast<char*>(szOID_RSA_RSA), 0, NULL,
- public_key_casted, &size);
- DCHECK(ok);
- if (!ok)
- return false;
-
- output->resize(size);
-
- return true;
-}
-
-// Generates a DER encoded SignedPublicKeyAndChallenge structure from the
-// signing key of |prov| and the specified ASCII |challenge| string and
-// appends it to |output|.
-// True if the encoding was successfully generated.
-bool GetSignedPublicKeyAndChallenge(HCRYPTPROV prov,
- const std::string& challenge,
- std::string* output) {
- base::string16 challenge16 = base::ASCIIToUTF16(challenge);
- std::vector<BYTE> spki;
-
- if (!GetSubjectPublicKeyInfo(prov, &spki))
- return false;
-
- // PublicKeyAndChallenge ::= SEQUENCE {
- // spki SubjectPublicKeyInfo,
- // challenge IA5STRING
- // }
- CERT_KEYGEN_REQUEST_INFO pkac;
- pkac.dwVersion = CERT_KEYGEN_REQUEST_V1;
- pkac.SubjectPublicKeyInfo =
- *reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&spki[0]);
- pkac.pwszChallengeString = const_cast<base::char16*>(challenge16.c_str());
-
- CRYPT_ALGORITHM_IDENTIFIER sig_alg;
- memset(&sig_alg, 0, sizeof(sig_alg));
- sig_alg.pszObjId = const_cast<char*>(szOID_RSA_MD5RSA);
-
- BOOL ok;
- DWORD size = 0;
- std::vector<BYTE> signed_pkac;
- ok = CryptSignAndEncodeCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- X509_KEYGEN_REQUEST_TO_BE_SIGNED,
- &pkac, &sig_alg, NULL,
- NULL, &size);
- DCHECK(ok);
- if (!ok)
- return false;
-
- signed_pkac.resize(size);
- ok = CryptSignAndEncodeCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- X509_KEYGEN_REQUEST_TO_BE_SIGNED,
- &pkac, &sig_alg, NULL,
- &signed_pkac[0], &size);
- DCHECK(ok);
- if (!ok)
- return false;
-
- output->assign(reinterpret_cast<char*>(&signed_pkac[0]), size);
- return true;
-}
-
-// Generates a unique name for the container which will store the key that is
-// generated. The traditional Windows approach is to use a GUID here.
-std::wstring GetNewKeyContainerId() {
- RPC_STATUS status = RPC_S_OK;
- std::wstring result;
-
- UUID id = { 0 };
- status = UuidCreateSequential(&id);
- if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY)
- return result;
-
- RPC_WSTR rpc_string = NULL;
- status = UuidToString(&id, &rpc_string);
- if (status != RPC_S_OK)
- return result;
-
- // RPC_WSTR is unsigned short*. wchar_t is a built-in type of Visual C++,
- // so the type cast is necessary.
- result.assign(reinterpret_cast<wchar_t*>(rpc_string));
- RpcStringFree(&rpc_string);
-
- return result;
-}
-
-// This is a helper struct designed to optionally delete a key after releasing
-// the associated provider.
-struct KeyContainer {
- public:
- explicit KeyContainer(bool delete_keyset)
- : delete_keyset_(delete_keyset) {}
-
- ~KeyContainer() {
- if (provider_) {
- provider_.reset();
- if (delete_keyset_ && !key_id_.empty()) {
- HCRYPTPROV provider;
- crypto::CryptAcquireContextLocked(&provider, key_id_.c_str(), NULL,
- PROV_RSA_FULL, CRYPT_SILENT | CRYPT_DELETEKEYSET);
- }
- }
- }
-
- crypto::ScopedHCRYPTPROV provider_;
- std::wstring key_id_;
-
- private:
- bool delete_keyset_;
-};
-
-std::string KeygenHandler::GenKeyAndSignChallenge() {
- KeyContainer key_container(!stores_key_);
-
- // TODO(rsleevi): Have the user choose which provider they should use, which
- // needs to be filtered by those providers which can provide the key type
- // requested or the key size requested. This is especially important for
- // generating certificates that will be stored on smart cards.
- const int kMaxAttempts = 5;
- int attempt;
- for (attempt = 0; attempt < kMaxAttempts; ++attempt) {
- // Per MSDN documentation for CryptAcquireContext, if applications will be
- // creating their own keys, they should ensure unique naming schemes to
- // prevent overlap with any other applications or consumers of CSPs, and
- // *should not* store new keys within the default, NULL key container.
- key_container.key_id_ = GetNewKeyContainerId();
- if (key_container.key_id_.empty())
- return std::string();
-
- // Only create new key containers, so that existing key containers are not
- // overwritten.
- if (crypto::CryptAcquireContextLocked(key_container.provider_.receive(),
- key_container.key_id_.c_str(), NULL, PROV_RSA_FULL,
- CRYPT_SILENT | CRYPT_NEWKEYSET))
- break;
-
- if (GetLastError() != static_cast<DWORD>(NTE_BAD_KEYSET)) {
- LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider "
- "context: " << GetLastError();
- return std::string();
- }
- }
- if (attempt == kMaxAttempts) {
- LOG(ERROR) << "Keygen failed: Couldn't acquire a CryptoAPI provider "
- "context: Max retries exceeded";
- return std::string();
- }
-
- {
- crypto::ScopedHCRYPTKEY key;
- if (!CryptGenKey(key_container.provider_, CALG_RSA_KEYX,
- (key_size_in_bits_ << 16) | CRYPT_EXPORTABLE, key.receive())) {
- LOG(ERROR) << "Keygen failed: Couldn't generate an RSA key";
- return std::string();
- }
-
- std::string spkac;
- if (!GetSignedPublicKeyAndChallenge(key_container.provider_, challenge_,
- &spkac)) {
- LOG(ERROR) << "Keygen failed: Couldn't generate the signed public key "
- "and challenge";
- return std::string();
- }
-
- std::string result;
- base::Base64Encode(spkac, &result);
-
- VLOG(1) << "Keygen succeeded";
- return result;
- }
-}
-
-} // namespace net
« no previous file with comments | « net/base/keygen_handler_unittest.cc ('k') | net/base/net_error_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698