WvStreams
|
00001 /* 00002 * Worldvisions Tunnel Vision Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * DSA cryptography abstractions. 00006 */ 00007 #include <assert.h> 00008 #include <openssl/dsa.h> 00009 #include <openssl/pem.h> 00010 #include "wvsslhacks.h" 00011 #include "wvdsa.h" 00012 #include "wvhex.h" 00013 00014 /***** WvDSAKey *****/ 00015 00016 WvDSAKey::WvDSAKey(const WvDSAKey &k) 00017 { 00018 if (k.prv) 00019 init(k.private_str(), true); 00020 else 00021 init(k.public_str(), false); 00022 } 00023 00024 00025 WvDSAKey::WvDSAKey(struct dsa_st *_dsa, bool priv) 00026 { 00027 if (_dsa == NULL) 00028 { 00029 // assert(_dsa); 00030 pub = WvString::null; 00031 prv = WvString::null; 00032 dsa = NULL; 00033 seterr("Initializing with a NULL key.. are you insane?"); 00034 return; 00035 } 00036 00037 dsa = _dsa; 00038 pub = hexifypub(dsa); 00039 if (priv) 00040 prv = hexifyprv(dsa); 00041 } 00042 00043 00044 WvDSAKey::WvDSAKey(WvStringParm keystr, bool priv) 00045 { 00046 init(keystr, priv); 00047 } 00048 00049 00050 WvDSAKey::WvDSAKey(int bits) 00051 { 00052 dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL); 00053 DSA_generate_key(dsa); 00054 pub = hexifypub(dsa); 00055 prv = hexifyprv(dsa); 00056 } 00057 00058 00059 WvDSAKey::~WvDSAKey() 00060 { 00061 if (dsa) 00062 DSA_free(dsa); 00063 } 00064 00065 00066 bool WvDSAKey::isok() const 00067 { 00068 return dsa && !errstring; 00069 } 00070 00071 00072 void WvDSAKey::init(WvStringParm keystr, bool priv) 00073 { 00074 // Start out with everything nulled out... 00075 dsa = NULL; 00076 pub = WvString::null; 00077 prv = WvString::null; 00078 00079 // unhexify the supplied key 00080 WvDynBuf keybuf; 00081 if (!WvHexDecoder().flushstrbuf(keystr, keybuf, true) || 00082 keybuf.used() == 0) 00083 { 00084 seterr("DSA key is not a valid hex string"); 00085 return; 00086 } 00087 00088 size_t keylen = keybuf.used(); 00089 const unsigned char *key = keybuf.get(keylen); 00090 00091 // create the DSA struct 00092 if (priv) 00093 { 00094 dsa = wv_d2i_DSAPrivateKey(NULL, &key, keylen); 00095 if (dsa != NULL) 00096 { 00097 prv = keystr; 00098 pub = hexifypub(dsa); 00099 } 00100 } 00101 else 00102 { 00103 dsa = wv_d2i_DSAPublicKey(NULL, &key, keylen); 00104 if (dsa != NULL) 00105 { 00106 prv = WvString::null; 00107 pub = keystr; 00108 } 00109 } 00110 if (dsa == NULL) 00111 seterr("DSA key is invalid"); 00112 } 00113 00114 00115 00116 WvString WvDSAKey::getpem(bool privkey) 00117 { 00118 FILE *fp = tmpfile(); 00119 const EVP_CIPHER *enc; 00120 00121 if (!fp) 00122 { 00123 seterr("Unable to open temporary file!"); 00124 return WvString::null; 00125 } 00126 00127 if (privkey) 00128 { 00129 enc = EVP_get_cipherbyname("dsa"); 00130 PEM_write_DSAPrivateKey(fp, dsa, enc, 00131 NULL, 0, NULL, NULL); 00132 } 00133 else 00134 { 00135 // We should write out the Public Key, which is the DSA Public 00136 // key, as well as the DH generator information. 00137 // PEM_write_DSAPublicKey(fp, dsa); 00138 } 00139 00140 WvDynBuf b; 00141 size_t len; 00142 00143 rewind(fp); 00144 while ((len = fread(b.alloc(1024), 1, 1024, fp)) > 0) 00145 b.unalloc(1024 - len); 00146 b.unalloc(1024 - len); 00147 fclose(fp); 00148 00149 return b.getstr(); 00150 } 00151 00152 00153 00154 WvString WvDSAKey::hexifypub(struct dsa_st *dsa) 00155 { 00156 WvDynBuf keybuf; 00157 00158 assert(dsa); 00159 00160 size_t size = i2d_DSAPublicKey(dsa, NULL); 00161 unsigned char *key = keybuf.alloc(size); 00162 size_t newsize = i2d_DSAPublicKey(dsa, & key); 00163 assert(size == newsize); 00164 assert(keybuf.used() == size); 00165 00166 return WvString(WvHexEncoder().strflushbuf(keybuf, true)); 00167 } 00168 00169 00170 WvString WvDSAKey::hexifyprv(struct dsa_st *dsa) 00171 { 00172 WvDynBuf keybuf; 00173 00174 assert(dsa); 00175 00176 size_t size = i2d_DSAPrivateKey(dsa, NULL); 00177 unsigned char *key = keybuf.alloc(size); 00178 size_t newsize = i2d_DSAPrivateKey(dsa, & key); 00179 assert(size == newsize); 00180 00181 return WvString(WvHexEncoder().strflushbuf(keybuf, true)); 00182 } 00183