1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef dtls_identity_h__ 7 #define dtls_identity_h__ 8 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "ScopedNSSTypes.h" 14 #include "m_cpp_utils.h" 15 #include "mozilla/RefPtr.h" 16 #include "nsISupportsImpl.h" 17 #include "nsTArray.h" 18 #include "sslt.h" 19 20 // All code in this module requires NSS to be live. 21 // Callers must initialize NSS and implement the nsNSSShutdownObject 22 // protocol. 23 namespace mozilla { 24 25 class DtlsDigest { 26 public: 27 const static size_t kMaxDtlsDigestLength = HASH_LENGTH_MAX; 28 DtlsDigest() = default; DtlsDigest(const std::string & algorithm)29 explicit DtlsDigest(const std::string& algorithm) : algorithm_(algorithm) {} DtlsDigest(const std::string & algorithm,const std::vector<uint8_t> & value)30 DtlsDigest(const std::string& algorithm, const std::vector<uint8_t>& value) 31 : algorithm_(algorithm), value_(value) { 32 MOZ_ASSERT(value.size() <= kMaxDtlsDigestLength); 33 } 34 ~DtlsDigest() = default; 35 36 bool operator!=(const DtlsDigest& rhs) const { return !operator==(rhs); } 37 38 bool operator==(const DtlsDigest& rhs) const { 39 if (algorithm_ != rhs.algorithm_) { 40 return false; 41 } 42 43 return value_ == rhs.value_; 44 } 45 46 std::string algorithm_; 47 std::vector<uint8_t> value_; 48 }; 49 50 typedef std::vector<DtlsDigest> DtlsDigestList; 51 52 class DtlsIdentity final { 53 public: 54 // This constructor takes ownership of privkey and cert. DtlsIdentity(UniqueSECKEYPrivateKey privkey,UniqueCERTCertificate cert,SSLKEAType authType)55 DtlsIdentity(UniqueSECKEYPrivateKey privkey, UniqueCERTCertificate cert, 56 SSLKEAType authType) 57 : private_key_(std::move(privkey)), 58 cert_(std::move(cert)), 59 auth_type_(authType) {} 60 61 // Allows serialization/deserialization; cannot write IPC serialization code 62 // directly for DtlsIdentity, since IPC-able types need to be constructable 63 // on the stack. 64 nsresult Serialize(nsTArray<uint8_t>* aKeyDer, nsTArray<uint8_t>* aCertDer); 65 static RefPtr<DtlsIdentity> Deserialize(const nsTArray<uint8_t>& aKeyDer, 66 const nsTArray<uint8_t>& aCertDer, 67 SSLKEAType authType); 68 69 // This is only for use in tests, or for external linkage. It makes a (bad) 70 // instance of this class. 71 static RefPtr<DtlsIdentity> Generate(); 72 73 // These don't create copies or transfer ownership. If you want these to live 74 // on, make a copy. cert()75 const UniqueCERTCertificate& cert() const { return cert_; } privkey()76 const UniqueSECKEYPrivateKey& privkey() const { return private_key_; } 77 // Note: this uses SSLKEAType because that is what the libssl API requires. 78 // This is a giant confusing mess, but libssl indexes certificates based on a 79 // key exchange type, not authentication type (as you might have reasonably 80 // expected). auth_type()81 SSLKEAType auth_type() const { return auth_type_; } 82 83 nsresult ComputeFingerprint(DtlsDigest* digest) const; 84 static nsresult ComputeFingerprint(const UniqueCERTCertificate& cert, 85 DtlsDigest* digest); 86 87 static const std::string DEFAULT_HASH_ALGORITHM; 88 enum { HASH_ALGORITHM_MAX_LENGTH = 64 }; 89 90 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DtlsIdentity) 91 92 private: 93 ~DtlsIdentity() = default; 94 DISALLOW_COPY_ASSIGN(DtlsIdentity); 95 96 UniqueSECKEYPrivateKey private_key_; 97 UniqueCERTCertificate cert_; 98 SSLKEAType auth_type_; 99 }; 100 } // namespace mozilla 101 #endif 102