1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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/. */
6 
7 // Generic key store implementation for platforms that we don't support with OS
8 // specific implementations.
9 
10 #ifndef OSKeyStore_h
11 #define OSKeyStore_h
12 
13 #include "nsCOMPtr.h"
14 #include "nsIOSKeyStore.h"
15 #include "nsString.h"
16 #include "ScopedNSSTypes.h"
17 
18 #include <memory>
19 #include <vector>
20 
21 class AbstractOSKeyStore {
22  public:
23   // Retrieve a secret with the given label.
24   virtual nsresult RetrieveSecret(const nsACString& aLabel,
25                                   /* out */ nsACString& aSecret) = 0;
26   // Store a new secret with the given label.
27   virtual nsresult StoreSecret(const nsACString& secret,
28                                const nsACString& label) = 0;
29   // Delete the secret with the given label.
30   virtual nsresult DeleteSecret(const nsACString& label) = 0;
31   // Lock the key store.
32   virtual nsresult Lock() = 0;
33   // Unlock the key store.
34   virtual nsresult Unlock() = 0;
35   virtual ~AbstractOSKeyStore() = default;
36 
37   // Returns true if the secret with the given label is available in the key
38   // store, false otherwise.
39   virtual bool SecretAvailable(const nsACString& label);
40   // Perform encryption or decryption operation with the given secret and input
41   // bytes. The output is written in outBytes. This function can make use of the
42   // AesGcm class to use NSS for encryption and decryption.
43   virtual nsresult EncryptDecrypt(const nsACString& label,
44                                   const std::vector<uint8_t>& inBytes,
45                                   std::vector<uint8_t>& outBytes, bool encrypt);
46 
GetKeyByteLength()47   size_t GetKeyByteLength() { return mKeyByteLength; }
48 
49  protected:
50   /* These helper functions are implemented in OSKeyStore.cpp and implement
51    * common functionality of the abstract key store to encrypt and decrypt.
52    */
53   nsresult DoCipher(const mozilla::UniquePK11SymKey& aSymKey,
54                     const std::vector<uint8_t>& inBytes,
55                     std::vector<uint8_t>& outBytes, bool aEncrypt);
56   nsresult BuildAesGcmKey(std::vector<uint8_t> keyBytes,
57                           /* out */ mozilla::UniquePK11SymKey& aKey);
58 
59  private:
60   const size_t mKeyByteLength = 16;
61   const size_t mIVLength = 12;
62 };
63 
64 #define NS_OSKEYSTORE_CONTRACTID "@mozilla.org/security/oskeystore;1"
65 #define NS_OSKEYSTORE_CID                            \
66   {                                                  \
67     0x57972956, 0x5718, 0x42d2, {                    \
68       0x80, 0x70, 0xb3, 0xfc, 0x72, 0x21, 0x2e, 0xaf \
69     }                                                \
70   }
71 
72 nsresult GetPromise(JSContext* aCx,
73                     /* out */ RefPtr<mozilla::dom::Promise>& aPromise);
74 
75 class OSKeyStore final : public nsIOSKeyStore {
76  public:
77   NS_DECL_THREADSAFE_ISUPPORTS
78   NS_DECL_NSIOSKEYSTORE
79 
80   OSKeyStore();
81   nsresult GenerateSecret(const nsACString& aLabel,
82                           /* out */ nsACString& aRecoveryPhrase);
83   nsresult SecretAvailable(const nsACString& aLabel,
84                            /* out */ bool* aAvailable);
85   nsresult RecoverSecret(const nsACString& aLabel,
86                          const nsACString& aRecoveryPhrase);
87   nsresult DeleteSecret(const nsACString& aLabel);
88   nsresult EncryptBytes(const nsACString& aLabel,
89                         const std::vector<uint8_t>& aInBytes,
90                         /*out*/ nsACString& aEncryptedBase64Text);
91   nsresult DecryptBytes(const nsACString& aLabel,
92                         const nsACString& aEncryptedBase64Text,
93                         /*out*/ uint32_t* outLen,
94                         /*out*/ uint8_t** outBytes);
95   nsresult Lock();
96   nsresult Unlock();
97 
98  private:
99   ~OSKeyStore() = default;
100 
101   std::unique_ptr<AbstractOSKeyStore> mKs;
102   bool mKsIsNSSKeyStore;
103   const nsCString mLabelPrefix =
104       NS_LITERAL_CSTRING("org.mozilla.nss.keystore.");
105 };
106 
107 #endif  // OSKeyStore_h
108