1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "CredentialManagerSecret.h"
12 #include "mozilla/Logging.h"
13 #include "mozilla/SyncRunnable.h"
15 // This is the implementation of CredentialManagerSecretSecret, an instantiation
16 // of OSKeyStore for Windows. It uses the system credential manager, hence the
19 using namespace mozilla
;
21 LazyLogModule
gCredentialManagerSecretLog("credentialmanagersecret");
23 void operator()(CREDENTIALA
* cred
) { CredFree(cred
); }
27 struct ScopedMaybeDelete
{
28 void operator()(T
* ptr
) {
35 typedef std::unique_ptr
<CREDENTIALA
, ScopedMaybeDelete
<CREDENTIALA
>>
38 CredentialManagerSecret::CredentialManagerSecret() {}
40 CredentialManagerSecret::~CredentialManagerSecret() {}
42 nsresult
CredentialManagerSecret::StoreSecret(const nsACString
& aSecret
,
43 const nsACString
& aLabel
) {
44 if (aSecret
.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE
) {
45 // Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE
47 MOZ_LOG(gCredentialManagerSecretLog
, LogLevel::Debug
,
48 ("StoreSecret secret must not be larger than 512 bytes (got %zd)",
50 return NS_ERROR_FAILURE
;
52 CREDENTIALA cred
= {0};
53 cred
.Type
= CRED_TYPE_GENERIC
;
54 const nsCString
& label
= PromiseFlatCString(aLabel
);
55 cred
.TargetName
= const_cast<LPSTR
>(label
.get());
56 cred
.CredentialBlobSize
= aSecret
.Length();
57 const nsCString
& secret
= PromiseFlatCString(aSecret
);
58 cred
.CredentialBlob
= (LPBYTE
)secret
.get();
59 cred
.Persist
= CRED_PERSIST_LOCAL_MACHINE
;
60 cred
.UserName
= const_cast<char*>(""); // -Wwritable-strings
62 // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea
63 BOOL ok
= CredWriteA(&cred
, 0);
65 MOZ_LOG(gCredentialManagerSecretLog
, LogLevel::Debug
,
66 ("CredWriteW failed %lu", GetLastError()));
67 return NS_ERROR_FAILURE
;
72 nsresult
CredentialManagerSecret::DeleteSecret(const nsACString
& aLabel
) {
73 // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea
74 const nsCString
& label
= PromiseFlatCString(aLabel
);
75 BOOL ok
= CredDeleteA(label
.get(), CRED_TYPE_GENERIC
, 0);
76 int error
= GetLastError();
77 if (!ok
&& error
!= ERROR_NOT_FOUND
) {
78 MOZ_LOG(gCredentialManagerSecretLog
, LogLevel::Debug
,
79 ("CredDeleteA failed %d", error
));
80 return NS_ERROR_FAILURE
;
85 nsresult
CredentialManagerSecret::RetrieveSecret(
86 const nsACString
& aLabel
,
87 /* out */ nsACString
& aSecret
) {
89 PCREDENTIALA pcred_raw
= nullptr;
90 const nsCString
& label
= PromiseFlatCString(aLabel
);
91 // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada
92 BOOL ok
= CredReadA(label
.get(), CRED_TYPE_GENERIC
, 0, &pcred_raw
);
93 ScopedCREDENTIALA
pcred(pcred_raw
);
95 MOZ_LOG(gCredentialManagerSecretLog
, LogLevel::Debug
,
96 ("CredReadA failed %lu", GetLastError()));
97 return NS_ERROR_FAILURE
;
100 aSecret
.Assign(reinterpret_cast<const char*>(pcred
->CredentialBlob
),
101 pcred
->CredentialBlobSize
);