00001 // Filename: prcKeyRegistry.cxx 00002 // Created by: drose (19Oct04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "prcKeyRegistry.h" 00016 #include "config_prc.h" 00017 00018 // This file requires OpenSSL to compile, because we use routines in 00019 // the OpenSSL library to manage keys and to sign and validate 00020 // signatures. 00021 00022 #ifdef HAVE_OPENSSL 00023 00024 #include "openssl/pem.h" 00025 00026 PrcKeyRegistry *PrcKeyRegistry::_global_ptr = NULL; 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: PrcKeyRegistry::Constructor 00030 // Access: Protected 00031 // Description: There is only one PrcKeyRegistry in the world; use 00032 // get_global_ptr() to get it. 00033 //////////////////////////////////////////////////////////////////// 00034 PrcKeyRegistry:: 00035 PrcKeyRegistry() { 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: PrcKeyRegistry::Destructor 00040 // Access: Protected 00041 // Description: 00042 //////////////////////////////////////////////////////////////////// 00043 PrcKeyRegistry:: 00044 ~PrcKeyRegistry() { 00045 prc_cat.error() 00046 << "Internal error--PrcKeyRegistry destructor called!\n"; 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: PrcKeyRegistry::record_keys 00051 // Access: Public 00052 // Description: Records the list of public keys that are compiled 00053 // into this executable. The pointer is assumed to be 00054 // to an area of static memory that will not be 00055 // destructed, so the data is not copied, but only the 00056 // pointer is assigned. 00057 // 00058 // This method is normally called after including the 00059 // code generated by the make-prc-key utility. 00060 //////////////////////////////////////////////////////////////////// 00061 void PrcKeyRegistry:: 00062 record_keys(const KeyDef *key_def, int num_keys) { 00063 for (int i = 0; i < num_keys; i++) { 00064 const KeyDef *def = &key_def[i]; 00065 if (def->_data != (char *)NULL) { 00066 // Clear the ith key. 00067 while ((int)_keys.size() <= i) { 00068 Key key; 00069 key._def = NULL; 00070 key._pkey = NULL; 00071 key._generated_time = 0; 00072 _keys.push_back(key); 00073 } 00074 if (_keys[i]._def != def) { 00075 if (_keys[i]._pkey != (EVP_PKEY *)NULL) { 00076 EVP_PKEY_free(_keys[i]._pkey); 00077 _keys[i]._pkey = NULL; 00078 } 00079 _keys[i]._def = def; 00080 _keys[i]._generated_time = def->_generated_time; 00081 } 00082 } 00083 } 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: PrcKeyRegistry::set_key 00088 // Access: Public 00089 // Description: Sets the nth public key in the registry to the given 00090 // value. The EVP_PKEY structure must have been 00091 // properly allocated view EVP_PKEY_new(); its ownership 00092 // is transferred to the registry and it will eventually 00093 // be freed via EVP_PKEY_free(). 00094 //////////////////////////////////////////////////////////////////// 00095 void PrcKeyRegistry:: 00096 set_key(int n, EVP_PKEY *pkey, time_t generated_time) { 00097 // Clear the nth key. 00098 while ((int)_keys.size() <= n) { 00099 Key key; 00100 key._def = NULL; 00101 key._pkey = NULL; 00102 key._generated_time = 0; 00103 _keys.push_back(key); 00104 } 00105 _keys[n]._def = NULL; 00106 if (_keys[n]._pkey != (EVP_PKEY *)NULL) { 00107 EVP_PKEY_free(_keys[n]._pkey); 00108 _keys[n]._pkey = NULL; 00109 } 00110 _keys[n]._pkey = pkey; 00111 _keys[n]._generated_time = generated_time; 00112 } 00113 00114 //////////////////////////////////////////////////////////////////// 00115 // Function: PrcKeyRegistry::get_num_keys 00116 // Access: Public 00117 // Description: Returns the number of public keys in the registry. 00118 // This is actually the highest index number + 1, which 00119 // might not strictly be the number of keys, since there 00120 // may be holes in the list. 00121 //////////////////////////////////////////////////////////////////// 00122 int PrcKeyRegistry:: 00123 get_num_keys() const { 00124 return _keys.size(); 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: PrcKeyRegistry::get_key 00129 // Access: Public 00130 // Description: Returns the nth public key, or NULL if the nth key is 00131 // not defined. 00132 //////////////////////////////////////////////////////////////////// 00133 EVP_PKEY *PrcKeyRegistry:: 00134 get_key(int n) const { 00135 nassertr(n >= 0 && n < (int)_keys.size(), (EVP_PKEY *)NULL); 00136 00137 if (_keys[n]._def != (KeyDef *)NULL) { 00138 if (_keys[n]._pkey == (EVP_PKEY *)NULL) { 00139 // Convert the def to a EVP_PKEY structure. 00140 const KeyDef *def = _keys[n]._def; 00141 BIO *mbio = BIO_new_mem_buf((void *)def->_data, def->_length); 00142 EVP_PKEY *pkey = PEM_read_bio_PUBKEY(mbio, NULL, NULL, NULL); 00143 ((PrcKeyRegistry *)this)->_keys[n]._pkey = pkey; 00144 BIO_free(mbio); 00145 00146 if (pkey == (EVP_PKEY *)NULL) { 00147 // Couldn't read the bio for some reason. 00148 ((PrcKeyRegistry *)this)->_keys[n]._def = NULL; 00149 } 00150 } 00151 } 00152 00153 return _keys[n]._pkey; 00154 } 00155 00156 //////////////////////////////////////////////////////////////////// 00157 // Function: PrcKeyRegistry::get_generated_time 00158 // Access: Public 00159 // Description: Returns the timestamp at which the indicated key was 00160 // generated, or 0 if the key is not defined. 00161 //////////////////////////////////////////////////////////////////// 00162 time_t PrcKeyRegistry:: 00163 get_generated_time(int n) const { 00164 nassertr(n >= 0 && n < (int)_keys.size(), 0); 00165 00166 return _keys[n]._generated_time; 00167 } 00168 00169 //////////////////////////////////////////////////////////////////// 00170 // Function: PrcKeyRegistry::get_global_ptr 00171 // Access: Public, Static 00172 // Description: 00173 //////////////////////////////////////////////////////////////////// 00174 PrcKeyRegistry *PrcKeyRegistry:: 00175 get_global_ptr() { 00176 if (_global_ptr == (PrcKeyRegistry *)NULL) { 00177 _global_ptr = new PrcKeyRegistry; 00178 } 00179 return _global_ptr; 00180 } 00181 00182 #endif // HAVE_OPENSSL