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