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 
7 #ifndef nss_policy_h_
8 #define nss_policy_h_
9 
10 #include "prtypes.h"
11 #include "secoid.h"
12 #include "nss.h"
13 
14 namespace nss_test {
15 
16 // container class to hold all a temp policy
17 class NssPolicy {
18  public:
NssPolicy()19   NssPolicy() : oid_(SEC_OID_UNKNOWN), set_(0), clear_(0) {}
NssPolicy(SECOidTag _oid,PRUint32 _set,PRUint32 _clear)20   NssPolicy(SECOidTag _oid, PRUint32 _set, PRUint32 _clear)
21       : oid_(_oid), set_(_set), clear_(_clear) {}
NssPolicy(const NssPolicy & p)22   NssPolicy(const NssPolicy &p)
23       : oid_(p.oid_), set_(p.set_), clear_(p.clear_) {}
24   // clone the current policy for this oid
NssPolicy(SECOidTag _oid)25   NssPolicy(SECOidTag _oid) : oid_(_oid), set_(0), clear_(0) {
26     NSS_GetAlgorithmPolicy(_oid, &set_);
27     clear_ = ~set_;
28   }
oid(void)29   SECOidTag oid(void) const { return oid_; }
set(void)30   PRUint32 set(void) const { return set_; }
clear(void)31   PRUint32 clear(void) const { return clear_; }
32   operator bool() const { return oid_ != SEC_OID_UNKNOWN; }
33 
34  private:
35   SECOidTag oid_;
36   PRUint32 set_;
37   PRUint32 clear_;
38 };
39 
40 // container class to hold a temp option
41 class NssOption {
42  public:
NssOption()43   NssOption() : id_(-1), value_(0) {}
NssOption(PRInt32 _id,PRInt32 _value)44   NssOption(PRInt32 _id, PRInt32 _value) : id_(_id), value_(_value) {}
NssOption(const NssOption & o)45   NssOption(const NssOption &o) : id_(o.id_), value_(o.value_) {}
46   // clone the current option for this id
NssOption(PRInt32 _id)47   NssOption(PRInt32 _id) : id_(_id), value_(0) { NSS_OptionGet(id_, &value_); }
id(void)48   PRInt32 id(void) const { return id_; }
value(void)49   PRInt32 value(void) const { return value_; }
50   operator bool() const { return id_ != -1; }
51 
52  private:
53   PRInt32 id_;
54   PRInt32 value_;
55 };
56 
57 // set the policy indicated in NssPolicy and restor the old policy
58 // when we go out of scope
59 class NssManagePolicy {
60  public:
NssManagePolicy(const NssPolicy & p,const NssOption & o)61   NssManagePolicy(const NssPolicy &p, const NssOption &o)
62       : policy_(p), save_policy_(~(PRUint32)0), option_(o), save_option_(0) {
63     if (p) {
64       (void)NSS_GetAlgorithmPolicy(p.oid(), &save_policy_);
65       (void)NSS_SetAlgorithmPolicy(p.oid(), p.set(), p.clear());
66     }
67     if (o) {
68       (void)NSS_OptionGet(o.id(), &save_option_);
69       (void)NSS_OptionSet(o.id(), o.value());
70     }
71   }
~NssManagePolicy()72   ~NssManagePolicy() {
73     if (policy_) {
74       (void)NSS_SetAlgorithmPolicy(policy_.oid(), save_policy_, ~save_policy_);
75     }
76     if (option_) {
77       (void)NSS_OptionSet(option_.id(), save_option_);
78     }
79   }
80 
81  private:
82   NssPolicy policy_;
83   PRUint32 save_policy_;
84   NssOption option_;
85   PRInt32 save_option_;
86 };
87 
88 // wrapping PRFileDesc this way ensures that tests that attempt to access
89 // PRFileDesc always correctly apply
90 // the policy that was bound to that socket with TlsAgent::SetPolicy().
91 class NssManagedFileDesc {
92  public:
NssManagedFileDesc(PRFileDesc * fd,const NssPolicy & policy,const NssOption & option)93   NssManagedFileDesc(PRFileDesc *fd, const NssPolicy &policy,
94                      const NssOption &option)
95       : fd_(fd), managed_policy_(policy, option) {}
get(void)96   PRFileDesc *get(void) const { return fd_; }
97   operator PRFileDesc *() const { return fd_; }
98   bool operator==(PRFileDesc *fd) const { return fd_ == fd; }
99 
100  private:
101   PRFileDesc *fd_;
102   NssManagePolicy managed_policy_;
103 };
104 
105 }  // namespace nss_test
106 
107 #endif
108