1 // Copyright 2019 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 "device/fido/win/logging.h"
6 
7 #include <string>
8 
9 #include "base/strings/string16.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_piece_forward.h"
12 #include "base/strings/string_util.h"
13 #include "components/device_event_log/device_event_log.h"
14 
15 namespace {
16 
17 constexpr char kSep[] = ", ";
18 
19 // Quoted wraps |in| in double quotes and backslash-escapes all other double
20 // quote characters.
Quoted(base::StringPiece in)21 std::string Quoted(base::StringPiece in) {
22   std::string result;
23   base::ReplaceChars(in, "\\", "\\\\", &result);
24   base::ReplaceChars(result, "\"", "\\\"", &result);
25   return "\"" + result + "\"";
26 }
27 
Quoted(base::WStringPiece in)28 std::wstring Quoted(base::WStringPiece in) {
29   std::wstring result;
30   base::ReplaceChars(in, L"\\", L"\\\\", &result);
31   base::ReplaceChars(result, L"\"", L"\\\"", &result);
32   return L"\"" + result + L"\"";
33 }
34 
Quoted(const wchar_t * in)35 std::wstring Quoted(const wchar_t* in) {
36   return Quoted(base::WStringPiece(in ? in : L""));
37 }
38 
39 }  // namespace
40 
operator <<(std::ostream & out,const WEBAUTHN_RP_ENTITY_INFORMATION & in)41 std::ostream& operator<<(std::ostream& out,
42                          const WEBAUTHN_RP_ENTITY_INFORMATION& in) {
43   return out << "{" << in.dwVersion << kSep << Quoted(in.pwszId) << kSep
44              << Quoted(in.pwszName) << kSep << Quoted(in.pwszIcon) << "}";
45 }
46 
operator <<(std::ostream & out,const WEBAUTHN_USER_ENTITY_INFORMATION & in)47 std::ostream& operator<<(std::ostream& out,
48                          const WEBAUTHN_USER_ENTITY_INFORMATION& in) {
49   return out << "{" << in.dwVersion << kSep << base::HexEncode(in.pbId, in.cbId)
50              << kSep << Quoted(in.pwszName) << kSep << Quoted(in.pwszIcon)
51              << kSep << Quoted(in.pwszDisplayName) << "}";
52 }
53 
operator <<(std::ostream & out,const WEBAUTHN_COSE_CREDENTIAL_PARAMETER & in)54 std::ostream& operator<<(std::ostream& out,
55                          const WEBAUTHN_COSE_CREDENTIAL_PARAMETER& in) {
56   return out << "{" << in.dwVersion << kSep << Quoted(in.pwszCredentialType)
57              << kSep << in.lAlg << "}";
58 }
59 
operator <<(std::ostream & out,const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS & in)60 std::ostream& operator<<(std::ostream& out,
61                          const WEBAUTHN_COSE_CREDENTIAL_PARAMETERS& in) {
62   out << "{" << in.cCredentialParameters << ", &[";
63   for (size_t i = 0; i < in.cCredentialParameters; ++i) {
64     out << (i ? kSep : "") << in.pCredentialParameters[i];
65   }
66   return out << "]}";
67 }
68 
operator <<(std::ostream & out,const WEBAUTHN_CLIENT_DATA & in)69 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_CLIENT_DATA& in) {
70   return out << "{" << in.dwVersion << kSep
71              << Quoted({reinterpret_cast<char*>(in.pbClientDataJSON),
72                         in.cbClientDataJSON})
73              << kSep << Quoted(in.pwszHashAlgId) << "}";
74 }
75 
operator <<(std::ostream & out,const WEBAUTHN_CREDENTIAL & in)76 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_CREDENTIAL& in) {
77   return out << "{" << in.dwVersion << kSep << base::HexEncode(in.pbId, in.cbId)
78              << kSep << Quoted(in.pwszCredentialType) << "}";
79 }
80 
operator <<(std::ostream & out,const WEBAUTHN_CREDENTIALS & in)81 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_CREDENTIALS& in) {
82   out << "{" << in.cCredentials << ", &[";
83   for (size_t i = 0; i < in.cCredentials; ++i) {
84     out << (i ? kSep : "") << in.pCredentials[i];
85   }
86   return out << "]}";
87 }
88 
operator <<(std::ostream & out,const WEBAUTHN_CREDENTIAL_EX & in)89 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_CREDENTIAL_EX& in) {
90   return out << "{" << in.dwVersion << kSep << base::HexEncode(in.pbId, in.cbId)
91              << kSep << Quoted(in.pwszCredentialType) << kSep << in.dwTransports
92              << "}";
93 }
94 
operator <<(std::ostream & out,const WEBAUTHN_CREDENTIAL_LIST & in)95 std::ostream& operator<<(std::ostream& out,
96                          const WEBAUTHN_CREDENTIAL_LIST& in) {
97   out << "{" << in.cCredentials << ", &[";
98   for (size_t i = 0; i < in.cCredentials; ++i) {
99     out << (i ? kSep : "") << "&" << *in.ppCredentials[i];
100   }
101   return out << "]}";
102 }
103 
operator <<(std::ostream & out,const WEBAUTHN_EXTENSION & in)104 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_EXTENSION& in) {
105   return out << "{" << Quoted(in.pwszExtensionIdentifier) << "}";
106 }
107 
operator <<(std::ostream & out,const WEBAUTHN_EXTENSIONS & in)108 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_EXTENSIONS& in) {
109   out << "{" << in.cExtensions << ", &[";
110   for (size_t i = 0; i < in.cExtensions; ++i) {
111     out << (i ? kSep : "") << in.pExtensions[i];
112   }
113   return out << "]}";
114 }
115 
operator <<(std::ostream & out,const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS & in)116 std::ostream& operator<<(
117     std::ostream& out,
118     const WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS& in) {
119   out << "{" << in.dwVersion << kSep << in.dwTimeoutMilliseconds << kSep
120       << in.CredentialList << kSep << in.Extensions << kSep
121       << in.dwAuthenticatorAttachment << kSep
122       << in.dwUserVerificationRequirement << kSep << in.dwFlags;
123   if (in.dwVersion < WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_2) {
124     return out << "}";
125   }
126   out << kSep << Quoted(in.pwszU2fAppId);
127   if (in.pbU2fAppId) {
128     out << ", &" << *in.pbU2fAppId;
129   } else {
130     out << ", (null)";
131   }
132   if (in.dwVersion < WEBAUTHN_AUTHENTICATOR_GET_ASSERTION_OPTIONS_VERSION_3) {
133     return out << "}";
134   }
135   if (in.pAllowCredentialList) {
136     out << ", &" << *in.pAllowCredentialList;
137   } else {
138     out << ", (null)";
139   }
140   return out << "}";
141 }
142 
operator <<(std::ostream & out,const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS & in)143 std::ostream& operator<<(
144     std::ostream& out,
145     const WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS& in) {
146   out << "{" << in.dwVersion << kSep << in.dwTimeoutMilliseconds << kSep
147       << in.CredentialList << kSep << in.Extensions << kSep
148       << in.dwAuthenticatorAttachment << kSep << in.bRequireResidentKey << kSep
149       << in.dwUserVerificationRequirement << kSep
150       << in.dwAttestationConveyancePreference << kSep << in.dwFlags;
151   if (in.dwVersion < WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_2) {
152     return out << "}";
153   }
154   out << kSep << in.pCancellationId;
155   if (in.dwVersion < WEBAUTHN_AUTHENTICATOR_MAKE_CREDENTIAL_OPTIONS_VERSION_3) {
156     return out << "}";
157   }
158   if (in.pExcludeCredentialList) {
159     out << ", &" << *in.pExcludeCredentialList;
160   } else {
161     out << ", (null)";
162   }
163   return out << "}";
164 }
165 
operator <<(std::ostream & out,const WEBAUTHN_CREDENTIAL_ATTESTATION & in)166 std::ostream& operator<<(std::ostream& out,
167                          const WEBAUTHN_CREDENTIAL_ATTESTATION& in) {
168   out << "{" << in.dwVersion << kSep << Quoted(in.pwszFormatType) << kSep
169       << base::HexEncode(in.pbAuthenticatorData, in.cbAuthenticatorData) << kSep
170       << base::HexEncode(in.pbAttestation, in.cbAttestation) << kSep
171       << in.dwAttestationDecodeType << kSep
172       << base::HexEncode(in.pbAttestationObject, in.cbAttestationObject) << kSep
173       << base::HexEncode(in.pbCredentialId, in.cbCredentialId);
174   if (in.dwVersion < WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_2) {
175     return out << "}";
176   }
177   out << kSep << in.Extensions;
178   if (in.dwVersion < WEBAUTHN_CREDENTIAL_ATTESTATION_VERSION_3) {
179     return out << "}";
180   }
181   out << kSep << in.dwUsedTransport;
182   return out << "}";
183 }
184 
operator <<(std::ostream & out,const WEBAUTHN_ASSERTION & in)185 std::ostream& operator<<(std::ostream& out, const WEBAUTHN_ASSERTION& in) {
186   return out << "{" << in.dwVersion << kSep
187              << base::HexEncode(in.pbAuthenticatorData, in.cbAuthenticatorData)
188              << kSep << base::HexEncode(in.pbSignature, in.cbSignature) << kSep
189              << in.Credential << kSep
190              << base::HexEncode(in.pbUserId, in.cbUserId) << "}";
191 }
192