Panda3D
 All Classes Functions Variables Enumerations
prcKeyRegistry.cxx
1 // Filename: prcKeyRegistry.cxx
2 // Created by: drose (19Oct04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "prcKeyRegistry.h"
16 #include "config_prc.h"
17 
18 // This file requires OpenSSL to compile, because we use routines in
19 // the OpenSSL library to manage keys and to sign and validate
20 // signatures.
21 
22 #ifdef HAVE_OPENSSL
23 
24 #include "openssl/pem.h"
25 
26 PrcKeyRegistry *PrcKeyRegistry::_global_ptr = NULL;
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: PrcKeyRegistry::Constructor
30 // Access: Protected
31 // Description: There is only one PrcKeyRegistry in the world; use
32 // get_global_ptr() to get it.
33 ////////////////////////////////////////////////////////////////////
34 PrcKeyRegistry::
35 PrcKeyRegistry() {
36 }
37 
38 ////////////////////////////////////////////////////////////////////
39 // Function: PrcKeyRegistry::Destructor
40 // Access: Protected
41 // Description:
42 ////////////////////////////////////////////////////////////////////
43 PrcKeyRegistry::
44 ~PrcKeyRegistry() {
45  prc_cat.error()
46  << "Internal error--PrcKeyRegistry destructor called!\n";
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: PrcKeyRegistry::record_keys
51 // Access: Public
52 // Description: Records the list of public keys that are compiled
53 // into this executable. The pointer is assumed to be
54 // to an area of static memory that will not be
55 // destructed, so the data is not copied, but only the
56 // pointer is assigned.
57 //
58 // This method is normally called after including the
59 // code generated by the make-prc-key utility.
60 ////////////////////////////////////////////////////////////////////
61 void PrcKeyRegistry::
62 record_keys(const KeyDef *key_def, int num_keys) {
63  for (int i = 0; i < num_keys; i++) {
64  const KeyDef *def = &key_def[i];
65  if (def->_data != (char *)NULL) {
66  // Clear the ith key.
67  while ((int)_keys.size() <= i) {
68  Key key;
69  key._def = NULL;
70  key._pkey = NULL;
71  key._generated_time = 0;
72  _keys.push_back(key);
73  }
74  if (_keys[i]._def != def) {
75  if (_keys[i]._pkey != (EVP_PKEY *)NULL) {
76  EVP_PKEY_free(_keys[i]._pkey);
77  _keys[i]._pkey = NULL;
78  }
79  _keys[i]._def = def;
80  _keys[i]._generated_time = def->_generated_time;
81  }
82  }
83  }
84 }
85 
86 ////////////////////////////////////////////////////////////////////
87 // Function: PrcKeyRegistry::set_key
88 // Access: Public
89 // Description: Sets the nth public key in the registry to the given
90 // value. The EVP_PKEY structure must have been
91 // properly allocated view EVP_PKEY_new(); its ownership
92 // is transferred to the registry and it will eventually
93 // be freed via EVP_PKEY_free().
94 ////////////////////////////////////////////////////////////////////
95 void PrcKeyRegistry::
96 set_key(int n, EVP_PKEY *pkey, time_t generated_time) {
97  // Clear the nth key.
98  while ((int)_keys.size() <= n) {
99  Key key;
100  key._def = NULL;
101  key._pkey = NULL;
102  key._generated_time = 0;
103  _keys.push_back(key);
104  }
105  _keys[n]._def = NULL;
106  if (_keys[n]._pkey != (EVP_PKEY *)NULL) {
107  EVP_PKEY_free(_keys[n]._pkey);
108  _keys[n]._pkey = NULL;
109  }
110  _keys[n]._pkey = pkey;
111  _keys[n]._generated_time = generated_time;
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: PrcKeyRegistry::get_num_keys
116 // Access: Public
117 // Description: Returns the number of public keys in the registry.
118 // This is actually the highest index number + 1, which
119 // might not strictly be the number of keys, since there
120 // may be holes in the list.
121 ////////////////////////////////////////////////////////////////////
122 int PrcKeyRegistry::
123 get_num_keys() const {
124  return _keys.size();
125 }
126 
127 ////////////////////////////////////////////////////////////////////
128 // Function: PrcKeyRegistry::get_key
129 // Access: Public
130 // Description: Returns the nth public key, or NULL if the nth key is
131 // not defined.
132 ////////////////////////////////////////////////////////////////////
133 EVP_PKEY *PrcKeyRegistry::
134 get_key(int n) const {
135  nassertr(n >= 0 && n < (int)_keys.size(), (EVP_PKEY *)NULL);
136 
137  if (_keys[n]._def != (KeyDef *)NULL) {
138  if (_keys[n]._pkey == (EVP_PKEY *)NULL) {
139  // Convert the def to a EVP_PKEY structure.
140  const KeyDef *def = _keys[n]._def;
141  BIO *mbio = BIO_new_mem_buf((void *)def->_data, def->_length);
142  EVP_PKEY *pkey = PEM_read_bio_PUBKEY(mbio, NULL, NULL, NULL);
143  ((PrcKeyRegistry *)this)->_keys[n]._pkey = pkey;
144  BIO_free(mbio);
145 
146  if (pkey == (EVP_PKEY *)NULL) {
147  // Couldn't read the bio for some reason.
148  ((PrcKeyRegistry *)this)->_keys[n]._def = NULL;
149  }
150  }
151  }
152 
153  return _keys[n]._pkey;
154 }
155 
156 ////////////////////////////////////////////////////////////////////
157 // Function: PrcKeyRegistry::get_generated_time
158 // Access: Public
159 // Description: Returns the timestamp at which the indicated key was
160 // generated, or 0 if the key is not defined.
161 ////////////////////////////////////////////////////////////////////
162 time_t PrcKeyRegistry::
163 get_generated_time(int n) const {
164  nassertr(n >= 0 && n < (int)_keys.size(), 0);
165 
166  return _keys[n]._generated_time;
167 }
168 
169 ////////////////////////////////////////////////////////////////////
170 // Function: PrcKeyRegistry::get_global_ptr
171 // Access: Public, Static
172 // Description:
173 ////////////////////////////////////////////////////////////////////
174 PrcKeyRegistry *PrcKeyRegistry::
175 get_global_ptr() {
176  if (_global_ptr == (PrcKeyRegistry *)NULL) {
177  _global_ptr = new PrcKeyRegistry;
178  }
179  return _global_ptr;
180 }
181 
182 #endif // HAVE_OPENSSL