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

Unified Diff: net/base/keygen_handler_win.cc

Issue 2021003: Simplify the Windows <keygen> implementation by making... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Add definition of PublicKeyAndChallenge and rename a variable pkac. Created 10 years, 7 months 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/keygen_handler_win.cc
===================================================================
--- net/base/keygen_handler_win.cc (revision 46590)
+++ net/base/keygen_handler_win.cc (working copy)
@@ -18,42 +18,11 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/string_piece.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
namespace net {
-// TODO(rsleevi): The following encoding functions are adapted from
-// base/crypto/rsa_private_key.h and can/should probably be refactored.
-static const uint8 kSequenceTag = 0x30;
-
-void PrependLength(size_t size, std::list<BYTE>* data) {
- // The high bit is used to indicate whether additional octets are needed to
- // represent the length.
- if (size < 0x80) {
- data->push_front(static_cast<BYTE>(size));
- } else {
- uint8 num_bytes = 0;
- while (size > 0) {
- data->push_front(static_cast<BYTE>(size & 0xFF));
- size >>= 8;
- num_bytes++;
- }
- CHECK_LE(num_bytes, 4);
- data->push_front(0x80 | num_bytes);
- }
-}
-
-void PrependTypeHeaderAndLength(uint8 type, uint32 length,
- std::vector<BYTE>* output) {
- std::list<BYTE> type_and_length;
-
- PrependLength(length, &type_and_length);
- type_and_length.push_front(type);
-
- output->insert(output->begin(), type_and_length.begin(),
- type_and_length.end());
-}
-
bool EncodeAndAppendType(LPCSTR type, const void* to_encode,
std::vector<BYTE>* output) {
BOOL ok;
@@ -79,22 +48,9 @@
return true;
}
-// Appends a DER IA5String containing |challenge| to |output|.
-// Returns true if encoding was successful.
-bool EncodeChallenge(const std::string& challenge, std::vector<BYTE>* output) {
- CERT_NAME_VALUE challenge_nv;
- challenge_nv.dwValueType = CERT_RDN_IA5_STRING;
- challenge_nv.Value.pbData = const_cast<BYTE*>(
- reinterpret_cast<const BYTE*>(challenge.data()));
- challenge_nv.Value.cbData = challenge.size();
-
- return EncodeAndAppendType(X509_ANY_STRING, &challenge_nv, output);
-}
-
-// Appends a DER SubjectPublicKeyInfo structure for the signing key in |prov|
-// to |output|.
-// Returns true if encoding was successful.
-bool EncodeSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
+// 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;
@@ -107,9 +63,10 @@
if (!ok)
return false;
- std::vector<BYTE> public_key_info(size);
+ output->resize(size);
+
PCERT_PUBLIC_KEY_INFO public_key_casted =
- reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&public_key_info[0]);
+ reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(&(*output)[0]);
ok = CryptExportPublicKeyInfoEx(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
szOID_RSA_RSA, 0, NULL, public_key_casted,
&size);
@@ -117,84 +74,71 @@
if (!ok)
return false;
- public_key_info.resize(size);
+ output->resize(size);
- return EncodeAndAppendType(X509_PUBLIC_KEY_INFO, &public_key_info[0],
- output);
+ return true;
}
-// Generates an ASN.1 DER representation of the PublicKeyAndChallenge structure
-// from the signing key of |prov| and the specified |challenge| and appends it
+// Appends a DER SubjectPublicKeyInfo structure for the signing key in |prov|
// to |output|.
-// True if the the encoding was successfully generated.
-bool GetPublicKeyAndChallenge(HCRYPTPROV prov, const std::string& challenge,
- std::vector<BYTE>* output) {
- if (!EncodeSubjectPublicKeyInfo(prov, output) ||
- !EncodeChallenge(challenge, output)) {
+// Returns true if encoding was successful.
+bool EncodeSubjectPublicKeyInfo(HCRYPTPROV prov, std::vector<BYTE>* output) {
+ std::vector<BYTE> public_key_info;
+ if (!GetSubjectPublicKeyInfo(prov, &public_key_info))
return false;
- }
- PrependTypeHeaderAndLength(kSequenceTag, output->size(), output);
- return true;
+ return EncodeAndAppendType(X509_PUBLIC_KEY_INFO, &public_key_info[0],
+ output);
}
// Generates a DER encoded SignedPublicKeyAndChallenge structure from the
-// signing key of |prov| and the specified |challenge| string and appends it
-// to |output|.
+// 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) {
- std::vector<BYTE> pkac;
- if (!GetPublicKeyAndChallenge(prov, challenge, &pkac))
+ std::wstring wide_challenge = ASCIIToWide(challenge);
+ std::vector<BYTE> spki;
+
+ if (!GetSubjectPublicKeyInfo(prov, &spki))
return false;
- std::vector<BYTE> signature;
- std::vector<BYTE> signed_pkac;
- DWORD size = 0;
- BOOL ok;
+ // 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<wchar_t*>(wide_challenge.c_str());
- // While the MSDN documentation states that CERT_SIGNED_CONTENT_INFO should
- // be an X.509 certificate type, for encoding this is not necessary. The
- // result of encoding this structure will be a DER-encoded structure with
- // the ASN.1 equivalent of
- // ::= SEQUENCE {
- // ToBeSigned IMPLICIT OCTET STRING,
- // SignatureAlgorithm AlgorithmIdentifier,
- // Signature BIT STRING
- // }
- //
- // This happens to be the same naive type as an SPKAC, so this works.
- CERT_SIGNED_CONTENT_INFO info;
- info.ToBeSigned.cbData = pkac.size();
- info.ToBeSigned.pbData = &pkac[0];
- info.SignatureAlgorithm.pszObjId = szOID_RSA_MD5RSA;
- info.SignatureAlgorithm.Parameters.cbData = 0;
- info.SignatureAlgorithm.Parameters.pbData = NULL;
+ CRYPT_ALGORITHM_IDENTIFIER sig_alg;
+ memset(&sig_alg, 0, sizeof(sig_alg));
+ sig_alg.pszObjId = szOID_RSA_MD5RSA;
- ok = CryptSignCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- info.ToBeSigned.pbData, info.ToBeSigned.cbData,
- &info.SignatureAlgorithm, NULL, NULL, &size);
+ 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;
- signature.resize(size);
- info.Signature.cbData = signature.size();
- info.Signature.pbData = &signature[0];
- info.Signature.cUnusedBits = 0;
-
- ok = CryptSignCertificate(prov, AT_KEYEXCHANGE, X509_ASN_ENCODING,
- info.ToBeSigned.pbData, info.ToBeSigned.cbData,
- &info.SignatureAlgorithm, NULL,
- info.Signature.pbData, &info.Signature.cbData);
+ 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 || !EncodeAndAppendType(X509_CERT, &info, &signed_pkac))
+ if (!ok)
return false;
- output->assign(reinterpret_cast<char*>(&signed_pkac[0]),
- signed_pkac.size());
-
+ output->assign(reinterpret_cast<char*>(&signed_pkac[0]), size);
return true;
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698