MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
crypto_wrapper.cpp
1 /* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
16 /* The crypto wrapper source implements the policies for the cipher
17  * components used by SSL.
18  *
19  * The implementation relies on a specfic library, taoCrypt.
20  */
21 
22 #if !defined(USE_CRYPTOPP_LIB)
23 
24 #include "runtime.hpp"
25 #include "crypto_wrapper.hpp"
26 #include "cert_wrapper.hpp"
27 
28 #include "md5.hpp"
29 #include "sha.hpp"
30 #include "ripemd.hpp"
31 #include "hmac.hpp"
32 #include "modes.hpp"
33 #include "des.hpp"
34 #include "arc4.hpp"
35 #include "aes.hpp"
36 #include "rsa.hpp"
37 #include "dsa.hpp"
38 #include "dh.hpp"
39 #include "random.hpp"
40 #include "file.hpp"
41 #include "coding.hpp"
42 
43 
44 namespace yaSSL {
45 
46 
47 // MD5 Implementation
48 struct MD5::MD5Impl {
49  TaoCrypt::MD5 md5_;
50  MD5Impl() {}
51  explicit MD5Impl(const TaoCrypt::MD5& md5) : md5_(md5) {}
52 };
53 
54 
55 MD5::MD5() : pimpl_(NEW_YS MD5Impl) {}
56 
57 
58 MD5::~MD5() { ysDelete(pimpl_); }
59 
60 
61 MD5::MD5(const MD5& that) : Digest(), pimpl_(NEW_YS
62  MD5Impl(that.pimpl_->md5_)) {}
63 
64 
65 MD5& MD5::operator=(const MD5& that)
66 {
67  pimpl_->md5_ = that.pimpl_->md5_;
68  return *this;
69 }
70 
71 
72 uint MD5::get_digestSize() const
73 {
74  return MD5_LEN;
75 }
76 
77 
78 uint MD5::get_padSize() const
79 {
80  return PAD_MD5;
81 }
82 
83 
84 // Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz
85 void MD5::get_digest(byte* out, const byte* in, unsigned int sz)
86 {
87  pimpl_->md5_.Update(in, sz);
88  pimpl_->md5_.Final(out);
89 }
90 
91 // Fill out with MD5 digest from previous updates
92 void MD5::get_digest(byte* out)
93 {
94  pimpl_->md5_.Final(out);
95 }
96 
97 
98 // Update the current digest
99 void MD5::update(const byte* in, unsigned int sz)
100 {
101  pimpl_->md5_.Update(in, sz);
102 }
103 
104 
105 // SHA Implementation
106 struct SHA::SHAImpl {
107  TaoCrypt::SHA sha_;
108  SHAImpl() {}
109  explicit SHAImpl(const TaoCrypt::SHA& sha) : sha_(sha) {}
110 };
111 
112 
113 SHA::SHA() : pimpl_(NEW_YS SHAImpl) {}
114 
115 
116 SHA::~SHA() { ysDelete(pimpl_); }
117 
118 
119 SHA::SHA(const SHA& that) : Digest(), pimpl_(NEW_YS SHAImpl(that.pimpl_->sha_)) {}
120 
121 SHA& SHA::operator=(const SHA& that)
122 {
123  pimpl_->sha_ = that.pimpl_->sha_;
124  return *this;
125 }
126 
127 
128 uint SHA::get_digestSize() const
129 {
130  return SHA_LEN;
131 }
132 
133 
134 uint SHA::get_padSize() const
135 {
136  return PAD_SHA;
137 }
138 
139 
140 // Fill out with SHA digest from in that is sz bytes, out must be >= digest sz
141 void SHA::get_digest(byte* out, const byte* in, unsigned int sz)
142 {
143  pimpl_->sha_.Update(in, sz);
144  pimpl_->sha_.Final(out);
145 }
146 
147 
148 // Fill out with SHA digest from previous updates
149 void SHA::get_digest(byte* out)
150 {
151  pimpl_->sha_.Final(out);
152 }
153 
154 
155 // Update the current digest
156 void SHA::update(const byte* in, unsigned int sz)
157 {
158  pimpl_->sha_.Update(in, sz);
159 }
160 
161 
162 // RMD-160 Implementation
163 struct RMD::RMDImpl {
164  TaoCrypt::RIPEMD160 rmd_;
165  RMDImpl() {}
166  explicit RMDImpl(const TaoCrypt::RIPEMD160& rmd) : rmd_(rmd) {}
167 };
168 
169 
170 RMD::RMD() : pimpl_(NEW_YS RMDImpl) {}
171 
172 
173 RMD::~RMD() { ysDelete(pimpl_); }
174 
175 
176 RMD::RMD(const RMD& that) : Digest(), pimpl_(NEW_YS RMDImpl(that.pimpl_->rmd_)) {}
177 
178 RMD& RMD::operator=(const RMD& that)
179 {
180  pimpl_->rmd_ = that.pimpl_->rmd_;
181  return *this;
182 }
183 
184 
185 uint RMD::get_digestSize() const
186 {
187  return RMD_LEN;
188 }
189 
190 
191 uint RMD::get_padSize() const
192 {
193  return PAD_RMD;
194 }
195 
196 
197 // Fill out with RMD digest from in that is sz bytes, out must be >= digest sz
198 void RMD::get_digest(byte* out, const byte* in, unsigned int sz)
199 {
200  pimpl_->rmd_.Update(in, sz);
201  pimpl_->rmd_.Final(out);
202 }
203 
204 
205 // Fill out with RMD digest from previous updates
206 void RMD::get_digest(byte* out)
207 {
208  pimpl_->rmd_.Final(out);
209 }
210 
211 
212 // Update the current digest
213 void RMD::update(const byte* in, unsigned int sz)
214 {
215  pimpl_->rmd_.Update(in, sz);
216 }
217 
218 
219 // HMAC_MD5 Implementation
222  HMAC_MD5Impl() {}
223 };
224 
225 
226 HMAC_MD5::HMAC_MD5(const byte* secret, unsigned int len)
227  : pimpl_(NEW_YS HMAC_MD5Impl)
228 {
229  pimpl_->mac_.SetKey(secret, len);
230 }
231 
232 
233 HMAC_MD5::~HMAC_MD5() { ysDelete(pimpl_); }
234 
235 
236 uint HMAC_MD5::get_digestSize() const
237 {
238  return MD5_LEN;
239 }
240 
241 
242 uint HMAC_MD5::get_padSize() const
243 {
244  return PAD_MD5;
245 }
246 
247 
248 // Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz
249 void HMAC_MD5::get_digest(byte* out, const byte* in, unsigned int sz)
250 {
251  pimpl_->mac_.Update(in, sz);
252  pimpl_->mac_.Final(out);
253 }
254 
255 // Fill out with MD5 digest from previous updates
256 void HMAC_MD5::get_digest(byte* out)
257 {
258  pimpl_->mac_.Final(out);
259 }
260 
261 
262 // Update the current digest
263 void HMAC_MD5::update(const byte* in, unsigned int sz)
264 {
265  pimpl_->mac_.Update(in, sz);
266 }
267 
268 
269 // HMAC_SHA Implementation
272  HMAC_SHAImpl() {}
273 };
274 
275 
276 HMAC_SHA::HMAC_SHA(const byte* secret, unsigned int len)
277  : pimpl_(NEW_YS HMAC_SHAImpl)
278 {
279  pimpl_->mac_.SetKey(secret, len);
280 }
281 
282 
283 HMAC_SHA::~HMAC_SHA() { ysDelete(pimpl_); }
284 
285 
286 uint HMAC_SHA::get_digestSize() const
287 {
288  return SHA_LEN;
289 }
290 
291 
292 uint HMAC_SHA::get_padSize() const
293 {
294  return PAD_SHA;
295 }
296 
297 
298 // Fill out with SHA digest from in that is sz bytes, out must be >= digest sz
299 void HMAC_SHA::get_digest(byte* out, const byte* in, unsigned int sz)
300 {
301  pimpl_->mac_.Update(in, sz);
302  pimpl_->mac_.Final(out);
303 }
304 
305 // Fill out with SHA digest from previous updates
306 void HMAC_SHA::get_digest(byte* out)
307 {
308  pimpl_->mac_.Final(out);
309 }
310 
311 
312 // Update the current digest
313 void HMAC_SHA::update(const byte* in, unsigned int sz)
314 {
315  pimpl_->mac_.Update(in, sz);
316 }
317 
318 
319 
320 // HMAC_RMD Implementation
323  HMAC_RMDImpl() {}
324 };
325 
326 
327 HMAC_RMD::HMAC_RMD(const byte* secret, unsigned int len)
328  : pimpl_(NEW_YS HMAC_RMDImpl)
329 {
330  pimpl_->mac_.SetKey(secret, len);
331 }
332 
333 
334 HMAC_RMD::~HMAC_RMD() { ysDelete(pimpl_); }
335 
336 
337 uint HMAC_RMD::get_digestSize() const
338 {
339  return RMD_LEN;
340 }
341 
342 
343 uint HMAC_RMD::get_padSize() const
344 {
345  return PAD_RMD;
346 }
347 
348 
349 // Fill out with RMD digest from in that is sz bytes, out must be >= digest sz
350 void HMAC_RMD::get_digest(byte* out, const byte* in, unsigned int sz)
351 {
352  pimpl_->mac_.Update(in, sz);
353  pimpl_->mac_.Final(out);
354 }
355 
356 // Fill out with RMD digest from previous updates
357 void HMAC_RMD::get_digest(byte* out)
358 {
359  pimpl_->mac_.Final(out);
360 }
361 
362 
363 // Update the current digest
364 void HMAC_RMD::update(const byte* in, unsigned int sz)
365 {
366  pimpl_->mac_.Update(in, sz);
367 }
368 
369 
370 struct DES::DESImpl {
371  TaoCrypt::DES_CBC_Encryption encryption;
372  TaoCrypt::DES_CBC_Decryption decryption;
373 };
374 
375 
376 DES::DES() : pimpl_(NEW_YS DESImpl) {}
377 
378 DES::~DES() { ysDelete(pimpl_); }
379 
380 
381 void DES::set_encryptKey(const byte* k, const byte* iv)
382 {
383  pimpl_->encryption.SetKey(k, DES_KEY_SZ, iv);
384 }
385 
386 
387 void DES::set_decryptKey(const byte* k, const byte* iv)
388 {
389  pimpl_->decryption.SetKey(k, DES_KEY_SZ, iv);
390 }
391 
392 // DES encrypt plain of length sz into cipher
393 void DES::encrypt(byte* cipher, const byte* plain, unsigned int sz)
394 {
395  pimpl_->encryption.Process(cipher, plain, sz);
396 }
397 
398 
399 // DES decrypt cipher of length sz into plain
400 void DES::decrypt(byte* plain, const byte* cipher, unsigned int sz)
401 {
402  pimpl_->decryption.Process(plain, cipher, sz);
403 }
404 
405 
409 };
410 
411 
412 DES_EDE::DES_EDE() : pimpl_(NEW_YS DES_EDEImpl) {}
413 
414 DES_EDE::~DES_EDE() { ysDelete(pimpl_); }
415 
416 
417 void DES_EDE::set_encryptKey(const byte* k, const byte* iv)
418 {
419  pimpl_->encryption.SetKey(k, DES_EDE_KEY_SZ, iv);
420 }
421 
422 
423 void DES_EDE::set_decryptKey(const byte* k, const byte* iv)
424 {
425  pimpl_->decryption.SetKey(k, DES_EDE_KEY_SZ, iv);
426 }
427 
428 
429 // 3DES encrypt plain of length sz into cipher
430 void DES_EDE::encrypt(byte* cipher, const byte* plain, unsigned int sz)
431 {
432  pimpl_->encryption.Process(cipher, plain, sz);
433 }
434 
435 
436 // 3DES decrypt cipher of length sz into plain
437 void DES_EDE::decrypt(byte* plain, const byte* cipher, unsigned int sz)
438 {
439  pimpl_->decryption.Process(plain, cipher, sz);
440 }
441 
442 
443 // Implementation of alledged RC4
444 struct RC4::RC4Impl {
445  TaoCrypt::ARC4::Encryption encryption;
446  TaoCrypt::ARC4::Decryption decryption;
447 };
448 
449 
450 RC4::RC4() : pimpl_(NEW_YS RC4Impl) {}
451 
452 RC4::~RC4() { ysDelete(pimpl_); }
453 
454 
455 void RC4::set_encryptKey(const byte* k, const byte*)
456 {
457  pimpl_->encryption.SetKey(k, RC4_KEY_SZ);
458 }
459 
460 
461 void RC4::set_decryptKey(const byte* k, const byte*)
462 {
463  pimpl_->decryption.SetKey(k, RC4_KEY_SZ);
464 }
465 
466 
467 // RC4 encrypt plain of length sz into cipher
468 void RC4::encrypt(byte* cipher, const byte* plain, unsigned int sz)
469 {
470  pimpl_->encryption.Process(cipher, plain, sz);
471 }
472 
473 
474 // RC4 decrypt cipher of length sz into plain
475 void RC4::decrypt(byte* plain, const byte* cipher, unsigned int sz)
476 {
477  pimpl_->decryption.Process(plain, cipher, sz);
478 }
479 
480 
481 
482 // Implementation of AES
483 struct AES::AESImpl {
484  TaoCrypt::AES_CBC_Encryption encryption;
485  TaoCrypt::AES_CBC_Decryption decryption;
486  unsigned int keySz_;
487 
488  AESImpl(unsigned int ks) : keySz_(ks) {}
489 };
490 
491 
492 AES::AES(unsigned int ks) : pimpl_(NEW_YS AESImpl(ks)) {}
493 
494 AES::~AES() { ysDelete(pimpl_); }
495 
496 
497 int AES::get_keySize() const
498 {
499  return pimpl_->keySz_;
500 }
501 
502 
503 void AES::set_encryptKey(const byte* k, const byte* iv)
504 {
505  pimpl_->encryption.SetKey(k, pimpl_->keySz_, iv);
506 }
507 
508 
509 void AES::set_decryptKey(const byte* k, const byte* iv)
510 {
511  pimpl_->decryption.SetKey(k, pimpl_->keySz_, iv);
512 }
513 
514 
515 // AES encrypt plain of length sz into cipher
516 void AES::encrypt(byte* cipher, const byte* plain, unsigned int sz)
517 {
518  pimpl_->encryption.Process(cipher, plain, sz);
519 }
520 
521 
522 // AES decrypt cipher of length sz into plain
523 void AES::decrypt(byte* plain, const byte* cipher, unsigned int sz)
524 {
525  pimpl_->decryption.Process(plain, cipher, sz);
526 }
527 
528 
531 };
532 
533 RandomPool::RandomPool() : pimpl_(NEW_YS RandomImpl) {}
534 
535 RandomPool::~RandomPool() { ysDelete(pimpl_); }
536 
537 int RandomPool::GetError() const
538 {
539  return pimpl_->RNG_.GetError();
540 }
541 
542 void RandomPool::Fill(opaque* dst, uint sz) const
543 {
544  pimpl_->RNG_.GenerateBlock(dst, sz);
545 }
546 
547 
548 // Implementation of DSS Authentication
549 struct DSS::DSSImpl {
550  void SetPublic (const byte*, unsigned int);
551  void SetPrivate(const byte*, unsigned int);
552  TaoCrypt::DSA_PublicKey publicKey_;
553  TaoCrypt::DSA_PrivateKey privateKey_;
554 };
555 
556 
557 // Decode and store the public key
558 void DSS::DSSImpl::SetPublic(const byte* key, unsigned int sz)
559 {
560  TaoCrypt::Source source(key, sz);
561  publicKey_.Initialize(source);
562 }
563 
564 
565 // Decode and store the public key
566 void DSS::DSSImpl::SetPrivate(const byte* key, unsigned int sz)
567 {
568  TaoCrypt::Source source(key, sz);
569  privateKey_.Initialize(source);
570  publicKey_ = TaoCrypt::DSA_PublicKey(privateKey_);
571 
572 }
573 
574 
575 // Set public or private key
576 DSS::DSS(const byte* key, unsigned int sz, bool publicKey)
577  : pimpl_(NEW_YS DSSImpl)
578 {
579  if (publicKey)
580  pimpl_->SetPublic(key, sz);
581  else
582  pimpl_->SetPrivate(key, sz);
583 }
584 
585 
586 DSS::~DSS()
587 {
588  ysDelete(pimpl_);
589 }
590 
591 
592 uint DSS::get_signatureLength() const
593 {
594  return pimpl_->publicKey_.SignatureLength();
595 }
596 
597 
598 // DSS Sign message of length sz into sig
599 void DSS::sign(byte* sig, const byte* sha_digest, unsigned int /* shaSz */,
600  const RandomPool& random)
601 {
602  using namespace TaoCrypt;
603 
604  DSA_Signer signer(pimpl_->privateKey_);
605  signer.Sign(sha_digest, sig, random.pimpl_->RNG_);
606 }
607 
608 
609 // DSS Verify message of length sz against sig, is it correct?
610 bool DSS::verify(const byte* sha_digest, unsigned int /* shaSz */,
611  const byte* sig, unsigned int /* sigSz */)
612 {
613  using namespace TaoCrypt;
614 
615  DSA_Verifier ver(pimpl_->publicKey_);
616  return ver.Verify(sha_digest, sig);
617 }
618 
619 
620 // Implementation of RSA key interface
621 struct RSA::RSAImpl {
622  void SetPublic (const byte*, unsigned int);
623  void SetPrivate(const byte*, unsigned int);
624  TaoCrypt::RSA_PublicKey publicKey_;
625  TaoCrypt::RSA_PrivateKey privateKey_;
626 };
627 
628 
629 // Decode and store the public key
630 void RSA::RSAImpl::SetPublic(const byte* key, unsigned int sz)
631 {
632  TaoCrypt::Source source(key, sz);
633  publicKey_.Initialize(source);
634 }
635 
636 
637 // Decode and store the private key
638 void RSA::RSAImpl::SetPrivate(const byte* key, unsigned int sz)
639 {
640  TaoCrypt::Source source(key, sz);
641  privateKey_.Initialize(source);
642  publicKey_ = TaoCrypt::RSA_PublicKey(privateKey_);
643 }
644 
645 
646 // Set public or private key
647 RSA::RSA(const byte* key, unsigned int sz, bool publicKey)
648  : pimpl_(NEW_YS RSAImpl)
649 {
650  if (publicKey)
651  pimpl_->SetPublic(key, sz);
652  else
653  pimpl_->SetPrivate(key, sz);
654 }
655 
656 RSA::~RSA()
657 {
658  ysDelete(pimpl_);
659 }
660 
661 
662 // get cipher text length, varies on key size
663 unsigned int RSA::get_cipherLength() const
664 {
665  return pimpl_->publicKey_.FixedCiphertextLength();
666 }
667 
668 
669 // get signautre length, varies on key size
670 unsigned int RSA::get_signatureLength() const
671 {
672  return get_cipherLength();
673 }
674 
675 
676 // RSA Sign message of length sz into sig
677 void RSA::sign(byte* sig, const byte* message, unsigned int sz,
678  const RandomPool& random)
679 {
680  TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_);
681  dec.SSL_Sign(message, sz, sig, random.pimpl_->RNG_);
682 }
683 
684 
685 // RSA Verify message of length sz against sig
686 bool RSA::verify(const byte* message, unsigned int sz, const byte* sig,
687  unsigned int)
688 {
689  TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_);
690  return enc.SSL_Verify(message, sz, sig);
691 }
692 
693 
694 // RSA public encrypt plain of length sz into cipher
695 void RSA::encrypt(byte* cipher, const byte* plain, unsigned int sz,
696  const RandomPool& random)
697 {
698 
699  TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_);
700  enc.Encrypt(plain, sz, cipher, random.pimpl_->RNG_);
701 }
702 
703 
704 // RSA private decrypt cipher of length sz into plain
705 void RSA::decrypt(byte* plain, const byte* cipher, unsigned int sz,
706  const RandomPool& random)
707 {
708  TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_);
709  dec.Decrypt(cipher, sz, plain, random.pimpl_->RNG_);
710 }
711 
712 
714  TaoCrypt::Integer int_;
715 
716  IntegerImpl() {}
717  explicit IntegerImpl(const TaoCrypt::Integer& i) : int_(i) {}
718 };
719 
720 Integer::Integer() : pimpl_(NEW_YS IntegerImpl) {}
721 
722 Integer::~Integer() { ysDelete(pimpl_); }
723 
724 
725 
726 Integer::Integer(const Integer& other) : pimpl_(NEW_YS
727  IntegerImpl(other.pimpl_->int_))
728 {}
729 
730 
731 Integer& Integer::operator=(const Integer& that)
732 {
733  pimpl_->int_ = that.pimpl_->int_;
734 
735  return *this;
736 }
737 
738 
739 void Integer::assign(const byte* num, unsigned int sz)
740 {
741  pimpl_->int_ = TaoCrypt::Integer(num, sz);
742 }
743 
744 
746  TaoCrypt::DH dh_;
748  byte* publicKey_;
749  byte* privateKey_;
750  byte* agreedKey_;
751 
752  DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0),
753  privateKey_(0), agreedKey_(0) {}
754  ~DHImpl()
755  {
756  ysArrayDelete(agreedKey_);
757  ysArrayDelete(privateKey_);
758  ysArrayDelete(publicKey_);
759  }
760 
761  DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_),
762  publicKey_(0), privateKey_(0), agreedKey_(0)
763  {
764  uint length = dh_.GetByteLength();
765  AllocKeys(length, length, length);
766  }
767 
768  void AllocKeys(unsigned int pubSz, unsigned int privSz, unsigned int agrSz)
769  {
770  publicKey_ = NEW_YS byte[pubSz];
771  privateKey_ = NEW_YS byte[privSz];
772  agreedKey_ = NEW_YS byte[agrSz];
773  }
774 };
775 
776 
777 
778 /*
779 // server Side DH, server's view
780 DiffieHellman::DiffieHellman(const char* file, const RandomPool& random)
781  : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
782 {
783  using namespace TaoCrypt;
784  Source source;
785  FileSource(file, source);
786  if (source.size() == 0)
787  return; // TODO add error state, and force check
788  HexDecoder hd(source);
789 
790  pimpl_->dh_.Initialize(source);
791 
792  uint length = pimpl_->dh_.GetByteLength();
793 
794  pimpl_->AllocKeys(length, length, length);
795  pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
796  pimpl_->publicKey_);
797 }
798 */
799 
800 
801 // server Side DH, client's view
802 DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g,
803  unsigned int gSz, const byte* pub,
804  unsigned int pubSz, const RandomPool& random)
805  : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
806 {
807  using TaoCrypt::Integer;
808 
809  pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref());
810  pimpl_->publicKey_ = NEW_YS opaque[pubSz];
811  memcpy(pimpl_->publicKey_, pub, pubSz);
812 }
813 
814 
815 // Server Side DH, server's view
816 DiffieHellman::DiffieHellman(const Integer& p, const Integer& g,
817  const RandomPool& random)
818 : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
819 {
820  using TaoCrypt::Integer;
821 
822  pimpl_->dh_.Initialize(p.pimpl_->int_, g.pimpl_->int_);
823 
824  uint length = pimpl_->dh_.GetByteLength();
825 
826  pimpl_->AllocKeys(length, length, length);
827  pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
828  pimpl_->publicKey_);
829 }
830 
831 DiffieHellman::~DiffieHellman() { ysDelete(pimpl_); }
832 
833 
834 // Client side and view, use server that for p and g
835 DiffieHellman::DiffieHellman(const DiffieHellman& that)
836  : pimpl_(NEW_YS DHImpl(*that.pimpl_))
837 {
838  pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
839  pimpl_->publicKey_);
840 }
841 
842 
843 DiffieHellman& DiffieHellman::operator=(const DiffieHellman& that)
844 {
845  pimpl_->dh_ = that.pimpl_->dh_;
846  pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
847  pimpl_->publicKey_);
848  return *this;
849 }
850 
851 
852 void DiffieHellman::makeAgreement(const byte* other, unsigned int otherSz)
853 {
854  pimpl_->dh_.Agree(pimpl_->agreedKey_, pimpl_->privateKey_, other, otherSz);
855 }
856 
857 
858 uint DiffieHellman::get_agreedKeyLength() const
859 {
860  return pimpl_->dh_.GetByteLength();
861 }
862 
863 
864 const byte* DiffieHellman::get_agreedKey() const
865 {
866  return pimpl_->agreedKey_;
867 }
868 
869 
870 const byte* DiffieHellman::get_publicKey() const
871 {
872  return pimpl_->publicKey_;
873 }
874 
875 
876 void DiffieHellman::set_sizes(int& pSz, int& gSz, int& pubSz) const
877 {
878  using TaoCrypt::Integer;
879  Integer p = pimpl_->dh_.GetP();
880  Integer g = pimpl_->dh_.GetG();
881 
882  pSz = p.ByteCount();
883  gSz = g.ByteCount();
884  pubSz = pimpl_->dh_.GetByteLength();
885 }
886 
887 
888 void DiffieHellman::get_parms(byte* bp, byte* bg, byte* bpub) const
889 {
890  using TaoCrypt::Integer;
891  Integer p = pimpl_->dh_.GetP();
892  Integer g = pimpl_->dh_.GetG();
893 
894  p.Encode(bp, p.ByteCount());
895  g.Encode(bg, g.ByteCount());
896  memcpy(bpub, pimpl_->publicKey_, pimpl_->dh_.GetByteLength());
897 }
898 
899 
900 // convert PEM file to DER x509 type
901 x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info)
902 {
903  using namespace TaoCrypt;
904 
905  char header[80];
906  char footer[80];
907 
908  if (type == Cert) {
909  strncpy(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
910  strncpy(footer, "-----END CERTIFICATE-----", sizeof(footer));
911  } else {
912  strncpy(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
913  strncpy(footer, "-----END RSA PRIVATE KEY-----", sizeof(header));
914  }
915 
916  long begin = -1;
917  long end = 0;
918  bool foundEnd = false;
919 
920  char line[80];
921 
922  while(fgets(line, sizeof(line), file))
923  if (strncmp(header, line, strlen(header)) == 0) {
924  begin = ftell(file);
925  break;
926  }
927 
928  // remove encrypted header if there
929  if (fgets(line, sizeof(line), file)) {
930  char encHeader[] = "Proc-Type";
931  if (strncmp(encHeader, line, strlen(encHeader)) == 0 &&
932  fgets(line,sizeof(line), file)) {
933 
934  char* start = strstr(line, "DES");
935  char* finish = strstr(line, ",");
936  if (!start)
937  start = strstr(line, "AES");
938 
939  if (!info) return 0;
940 
941  if ( start && finish && (start < finish)) {
942  memcpy(info->name, start, finish - start);
943  info->name[finish - start] = 0;
944  memcpy(info->iv, finish + 1, sizeof(info->iv));
945 
946  char* newline = strstr(line, "\r");
947  if (!newline) newline = strstr(line, "\n");
948  if (newline && (newline > finish)) {
949  info->ivSz = newline - (finish + 1);
950  info->set = true;
951  }
952  }
953  // get blank line
954  if (fgets(line, sizeof(line), file))
955  begin = ftell(file);
956  }
957 
958  }
959 
960  while(fgets(line, sizeof(line), file))
961  if (strncmp(footer, line, strlen(footer)) == 0) {
962  foundEnd = true;
963  break;
964  }
965  else
966  end = ftell(file);
967 
968  if (begin == -1 || !foundEnd)
969  return 0;
970 
971  input_buffer tmp(end - begin);
972  fseek(file, begin, SEEK_SET);
973  size_t bytes = fread(tmp.get_buffer(), end - begin, 1, file);
974  if (bytes != 1)
975  return 0;
976 
977  Source der(tmp.get_buffer(), end - begin);
978  Base64Decoder b64Dec(der);
979 
980  uint sz = der.size();
981  mySTL::auto_ptr<x509> x(NEW_YS x509(sz));
982  memcpy(x->use_buffer(), der.get_buffer(), sz);
983 
984  return x.release();
985 }
986 
987 
988 } // namespace
989 
990 
991 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
992 namespace yaSSL {
993 template void ysDelete<DiffieHellman::DHImpl>(DiffieHellman::DHImpl*);
994 template void ysDelete<Integer::IntegerImpl>(Integer::IntegerImpl*);
995 template void ysDelete<RSA::RSAImpl>(RSA::RSAImpl*);
996 template void ysDelete<DSS::DSSImpl>(DSS::DSSImpl*);
997 template void ysDelete<RandomPool::RandomImpl>(RandomPool::RandomImpl*);
998 template void ysDelete<AES::AESImpl>(AES::AESImpl*);
999 template void ysDelete<RC4::RC4Impl>(RC4::RC4Impl*);
1000 template void ysDelete<DES_EDE::DES_EDEImpl>(DES_EDE::DES_EDEImpl*);
1001 template void ysDelete<DES::DESImpl>(DES::DESImpl*);
1002 template void ysDelete<HMAC_RMD::HMAC_RMDImpl>(HMAC_RMD::HMAC_RMDImpl*);
1003 template void ysDelete<HMAC_SHA::HMAC_SHAImpl>(HMAC_SHA::HMAC_SHAImpl*);
1004 template void ysDelete<HMAC_MD5::HMAC_MD5Impl>(HMAC_MD5::HMAC_MD5Impl*);
1005 template void ysDelete<RMD::RMDImpl>(RMD::RMDImpl*);
1006 template void ysDelete<SHA::SHAImpl>(SHA::SHAImpl*);
1007 template void ysDelete<MD5::MD5Impl>(MD5::MD5Impl*);
1008 }
1009 #endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1010 
1011 #endif // !USE_CRYPTOPP_LIB