mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / extra / yassl / src / crypto_wrapper.cpp
blobd8952d0daf089d85970a17b549ee7f950299d712
1 /*
2 Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to the
15 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16 MA 02110-1301 USA.
19 /* The crypto wrapper source implements the policies for the cipher
20 * components used by SSL.
22 * The implementation relies on a specfic library, taoCrypt.
25 #if !defined(USE_CRYPTOPP_LIB)
27 #include "runtime.hpp"
28 #include "crypto_wrapper.hpp"
29 #include "cert_wrapper.hpp"
31 #include "md5.hpp"
32 #include "sha.hpp"
33 #include "ripemd.hpp"
34 #include "hmac.hpp"
35 #include "modes.hpp"
36 #include "des.hpp"
37 #include "arc4.hpp"
38 #include "aes.hpp"
39 #include "rsa.hpp"
40 #include "dsa.hpp"
41 #include "dh.hpp"
42 #include "random.hpp"
43 #include "file.hpp"
44 #include "coding.hpp"
47 namespace yaSSL {
50 // MD5 Implementation
51 struct MD5::MD5Impl {
52 TaoCrypt::MD5 md5_;
53 MD5Impl() {}
54 explicit MD5Impl(const TaoCrypt::MD5& md5) : md5_(md5) {}
58 MD5::MD5() : pimpl_(NEW_YS MD5Impl) {}
61 MD5::~MD5() { ysDelete(pimpl_); }
64 MD5::MD5(const MD5& that) : Digest(), pimpl_(NEW_YS
65 MD5Impl(that.pimpl_->md5_)) {}
68 MD5& MD5::operator=(const MD5& that)
70 pimpl_->md5_ = that.pimpl_->md5_;
71 return *this;
75 uint MD5::get_digestSize() const
77 return MD5_LEN;
81 uint MD5::get_padSize() const
83 return PAD_MD5;
87 // Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz
88 void MD5::get_digest(byte* out, const byte* in, unsigned int sz)
90 pimpl_->md5_.Update(in, sz);
91 pimpl_->md5_.Final(out);
94 // Fill out with MD5 digest from previous updates
95 void MD5::get_digest(byte* out)
97 pimpl_->md5_.Final(out);
101 // Update the current digest
102 void MD5::update(const byte* in, unsigned int sz)
104 pimpl_->md5_.Update(in, sz);
108 // SHA Implementation
109 struct SHA::SHAImpl {
110 TaoCrypt::SHA sha_;
111 SHAImpl() {}
112 explicit SHAImpl(const TaoCrypt::SHA& sha) : sha_(sha) {}
116 SHA::SHA() : pimpl_(NEW_YS SHAImpl) {}
119 SHA::~SHA() { ysDelete(pimpl_); }
122 SHA::SHA(const SHA& that) : Digest(), pimpl_(NEW_YS SHAImpl(that.pimpl_->sha_)) {}
124 SHA& SHA::operator=(const SHA& that)
126 pimpl_->sha_ = that.pimpl_->sha_;
127 return *this;
131 uint SHA::get_digestSize() const
133 return SHA_LEN;
137 uint SHA::get_padSize() const
139 return PAD_SHA;
143 // Fill out with SHA digest from in that is sz bytes, out must be >= digest sz
144 void SHA::get_digest(byte* out, const byte* in, unsigned int sz)
146 pimpl_->sha_.Update(in, sz);
147 pimpl_->sha_.Final(out);
151 // Fill out with SHA digest from previous updates
152 void SHA::get_digest(byte* out)
154 pimpl_->sha_.Final(out);
158 // Update the current digest
159 void SHA::update(const byte* in, unsigned int sz)
161 pimpl_->sha_.Update(in, sz);
165 // RMD-160 Implementation
166 struct RMD::RMDImpl {
167 TaoCrypt::RIPEMD160 rmd_;
168 RMDImpl() {}
169 explicit RMDImpl(const TaoCrypt::RIPEMD160& rmd) : rmd_(rmd) {}
173 RMD::RMD() : pimpl_(NEW_YS RMDImpl) {}
176 RMD::~RMD() { ysDelete(pimpl_); }
179 RMD::RMD(const RMD& that) : Digest(), pimpl_(NEW_YS RMDImpl(that.pimpl_->rmd_)) {}
181 RMD& RMD::operator=(const RMD& that)
183 pimpl_->rmd_ = that.pimpl_->rmd_;
184 return *this;
188 uint RMD::get_digestSize() const
190 return RMD_LEN;
194 uint RMD::get_padSize() const
196 return PAD_RMD;
200 // Fill out with RMD digest from in that is sz bytes, out must be >= digest sz
201 void RMD::get_digest(byte* out, const byte* in, unsigned int sz)
203 pimpl_->rmd_.Update(in, sz);
204 pimpl_->rmd_.Final(out);
208 // Fill out with RMD digest from previous updates
209 void RMD::get_digest(byte* out)
211 pimpl_->rmd_.Final(out);
215 // Update the current digest
216 void RMD::update(const byte* in, unsigned int sz)
218 pimpl_->rmd_.Update(in, sz);
222 // HMAC_MD5 Implementation
223 struct HMAC_MD5::HMAC_MD5Impl {
224 TaoCrypt::HMAC<TaoCrypt::MD5> mac_;
225 HMAC_MD5Impl() {}
229 HMAC_MD5::HMAC_MD5(const byte* secret, unsigned int len)
230 : pimpl_(NEW_YS HMAC_MD5Impl)
232 pimpl_->mac_.SetKey(secret, len);
236 HMAC_MD5::~HMAC_MD5() { ysDelete(pimpl_); }
239 uint HMAC_MD5::get_digestSize() const
241 return MD5_LEN;
245 uint HMAC_MD5::get_padSize() const
247 return PAD_MD5;
251 // Fill out with MD5 digest from in that is sz bytes, out must be >= digest sz
252 void HMAC_MD5::get_digest(byte* out, const byte* in, unsigned int sz)
254 pimpl_->mac_.Update(in, sz);
255 pimpl_->mac_.Final(out);
258 // Fill out with MD5 digest from previous updates
259 void HMAC_MD5::get_digest(byte* out)
261 pimpl_->mac_.Final(out);
265 // Update the current digest
266 void HMAC_MD5::update(const byte* in, unsigned int sz)
268 pimpl_->mac_.Update(in, sz);
272 // HMAC_SHA Implementation
273 struct HMAC_SHA::HMAC_SHAImpl {
274 TaoCrypt::HMAC<TaoCrypt::SHA> mac_;
275 HMAC_SHAImpl() {}
279 HMAC_SHA::HMAC_SHA(const byte* secret, unsigned int len)
280 : pimpl_(NEW_YS HMAC_SHAImpl)
282 pimpl_->mac_.SetKey(secret, len);
286 HMAC_SHA::~HMAC_SHA() { ysDelete(pimpl_); }
289 uint HMAC_SHA::get_digestSize() const
291 return SHA_LEN;
295 uint HMAC_SHA::get_padSize() const
297 return PAD_SHA;
301 // Fill out with SHA digest from in that is sz bytes, out must be >= digest sz
302 void HMAC_SHA::get_digest(byte* out, const byte* in, unsigned int sz)
304 pimpl_->mac_.Update(in, sz);
305 pimpl_->mac_.Final(out);
308 // Fill out with SHA digest from previous updates
309 void HMAC_SHA::get_digest(byte* out)
311 pimpl_->mac_.Final(out);
315 // Update the current digest
316 void HMAC_SHA::update(const byte* in, unsigned int sz)
318 pimpl_->mac_.Update(in, sz);
323 // HMAC_RMD Implementation
324 struct HMAC_RMD::HMAC_RMDImpl {
325 TaoCrypt::HMAC<TaoCrypt::RIPEMD160> mac_;
326 HMAC_RMDImpl() {}
330 HMAC_RMD::HMAC_RMD(const byte* secret, unsigned int len)
331 : pimpl_(NEW_YS HMAC_RMDImpl)
333 pimpl_->mac_.SetKey(secret, len);
337 HMAC_RMD::~HMAC_RMD() { ysDelete(pimpl_); }
340 uint HMAC_RMD::get_digestSize() const
342 return RMD_LEN;
346 uint HMAC_RMD::get_padSize() const
348 return PAD_RMD;
352 // Fill out with RMD digest from in that is sz bytes, out must be >= digest sz
353 void HMAC_RMD::get_digest(byte* out, const byte* in, unsigned int sz)
355 pimpl_->mac_.Update(in, sz);
356 pimpl_->mac_.Final(out);
359 // Fill out with RMD digest from previous updates
360 void HMAC_RMD::get_digest(byte* out)
362 pimpl_->mac_.Final(out);
366 // Update the current digest
367 void HMAC_RMD::update(const byte* in, unsigned int sz)
369 pimpl_->mac_.Update(in, sz);
373 struct DES::DESImpl {
374 TaoCrypt::DES_CBC_Encryption encryption;
375 TaoCrypt::DES_CBC_Decryption decryption;
379 DES::DES() : pimpl_(NEW_YS DESImpl) {}
381 DES::~DES() { ysDelete(pimpl_); }
384 void DES::set_encryptKey(const byte* k, const byte* iv)
386 pimpl_->encryption.SetKey(k, DES_KEY_SZ, iv);
390 void DES::set_decryptKey(const byte* k, const byte* iv)
392 pimpl_->decryption.SetKey(k, DES_KEY_SZ, iv);
395 // DES encrypt plain of length sz into cipher
396 void DES::encrypt(byte* cipher, const byte* plain, unsigned int sz)
398 pimpl_->encryption.Process(cipher, plain, sz);
402 // DES decrypt cipher of length sz into plain
403 void DES::decrypt(byte* plain, const byte* cipher, unsigned int sz)
405 pimpl_->decryption.Process(plain, cipher, sz);
409 struct DES_EDE::DES_EDEImpl {
410 TaoCrypt::DES_EDE3_CBC_Encryption encryption;
411 TaoCrypt::DES_EDE3_CBC_Decryption decryption;
415 DES_EDE::DES_EDE() : pimpl_(NEW_YS DES_EDEImpl) {}
417 DES_EDE::~DES_EDE() { ysDelete(pimpl_); }
420 void DES_EDE::set_encryptKey(const byte* k, const byte* iv)
422 pimpl_->encryption.SetKey(k, DES_EDE_KEY_SZ, iv);
426 void DES_EDE::set_decryptKey(const byte* k, const byte* iv)
428 pimpl_->decryption.SetKey(k, DES_EDE_KEY_SZ, iv);
432 // 3DES encrypt plain of length sz into cipher
433 void DES_EDE::encrypt(byte* cipher, const byte* plain, unsigned int sz)
435 pimpl_->encryption.Process(cipher, plain, sz);
439 // 3DES decrypt cipher of length sz into plain
440 void DES_EDE::decrypt(byte* plain, const byte* cipher, unsigned int sz)
442 pimpl_->decryption.Process(plain, cipher, sz);
446 // Implementation of alledged RC4
447 struct RC4::RC4Impl {
448 TaoCrypt::ARC4::Encryption encryption;
449 TaoCrypt::ARC4::Decryption decryption;
453 RC4::RC4() : pimpl_(NEW_YS RC4Impl) {}
455 RC4::~RC4() { ysDelete(pimpl_); }
458 void RC4::set_encryptKey(const byte* k, const byte*)
460 pimpl_->encryption.SetKey(k, RC4_KEY_SZ);
464 void RC4::set_decryptKey(const byte* k, const byte*)
466 pimpl_->decryption.SetKey(k, RC4_KEY_SZ);
470 // RC4 encrypt plain of length sz into cipher
471 void RC4::encrypt(byte* cipher, const byte* plain, unsigned int sz)
473 pimpl_->encryption.Process(cipher, plain, sz);
477 // RC4 decrypt cipher of length sz into plain
478 void RC4::decrypt(byte* plain, const byte* cipher, unsigned int sz)
480 pimpl_->decryption.Process(plain, cipher, sz);
485 // Implementation of AES
486 struct AES::AESImpl {
487 TaoCrypt::AES_CBC_Encryption encryption;
488 TaoCrypt::AES_CBC_Decryption decryption;
489 unsigned int keySz_;
491 AESImpl(unsigned int ks) : keySz_(ks) {}
495 AES::AES(unsigned int ks) : pimpl_(NEW_YS AESImpl(ks)) {}
497 AES::~AES() { ysDelete(pimpl_); }
500 int AES::get_keySize() const
502 return pimpl_->keySz_;
506 void AES::set_encryptKey(const byte* k, const byte* iv)
508 pimpl_->encryption.SetKey(k, pimpl_->keySz_, iv);
512 void AES::set_decryptKey(const byte* k, const byte* iv)
514 pimpl_->decryption.SetKey(k, pimpl_->keySz_, iv);
518 // AES encrypt plain of length sz into cipher
519 void AES::encrypt(byte* cipher, const byte* plain, unsigned int sz)
521 pimpl_->encryption.Process(cipher, plain, sz);
525 // AES decrypt cipher of length sz into plain
526 void AES::decrypt(byte* plain, const byte* cipher, unsigned int sz)
528 pimpl_->decryption.Process(plain, cipher, sz);
532 struct RandomPool::RandomImpl {
533 TaoCrypt::RandomNumberGenerator RNG_;
536 RandomPool::RandomPool() : pimpl_(NEW_YS RandomImpl) {}
538 RandomPool::~RandomPool() { ysDelete(pimpl_); }
540 int RandomPool::GetError() const
542 return pimpl_->RNG_.GetError();
545 void RandomPool::Fill(opaque* dst, uint sz) const
547 pimpl_->RNG_.GenerateBlock(dst, sz);
551 // Implementation of DSS Authentication
552 struct DSS::DSSImpl {
553 void SetPublic (const byte*, unsigned int);
554 void SetPrivate(const byte*, unsigned int);
555 TaoCrypt::DSA_PublicKey publicKey_;
556 TaoCrypt::DSA_PrivateKey privateKey_;
560 // Decode and store the public key
561 void DSS::DSSImpl::SetPublic(const byte* key, unsigned int sz)
563 TaoCrypt::Source source(key, sz);
564 publicKey_.Initialize(source);
568 // Decode and store the public key
569 void DSS::DSSImpl::SetPrivate(const byte* key, unsigned int sz)
571 TaoCrypt::Source source(key, sz);
572 privateKey_.Initialize(source);
573 publicKey_ = TaoCrypt::DSA_PublicKey(privateKey_);
578 // Set public or private key
579 DSS::DSS(const byte* key, unsigned int sz, bool publicKey)
580 : pimpl_(NEW_YS DSSImpl)
582 if (publicKey)
583 pimpl_->SetPublic(key, sz);
584 else
585 pimpl_->SetPrivate(key, sz);
589 DSS::~DSS()
591 ysDelete(pimpl_);
595 uint DSS::get_signatureLength() const
597 return pimpl_->publicKey_.SignatureLength();
601 // DSS Sign message of length sz into sig
602 void DSS::sign(byte* sig, const byte* sha_digest, unsigned int /* shaSz */,
603 const RandomPool& random)
605 using namespace TaoCrypt;
607 DSA_Signer signer(pimpl_->privateKey_);
608 signer.Sign(sha_digest, sig, random.pimpl_->RNG_);
612 // DSS Verify message of length sz against sig, is it correct?
613 bool DSS::verify(const byte* sha_digest, unsigned int /* shaSz */,
614 const byte* sig, unsigned int /* sigSz */)
616 using namespace TaoCrypt;
618 DSA_Verifier ver(pimpl_->publicKey_);
619 return ver.Verify(sha_digest, sig);
623 // Implementation of RSA key interface
624 struct RSA::RSAImpl {
625 void SetPublic (const byte*, unsigned int);
626 void SetPrivate(const byte*, unsigned int);
627 TaoCrypt::RSA_PublicKey publicKey_;
628 TaoCrypt::RSA_PrivateKey privateKey_;
632 // Decode and store the public key
633 void RSA::RSAImpl::SetPublic(const byte* key, unsigned int sz)
635 TaoCrypt::Source source(key, sz);
636 publicKey_.Initialize(source);
640 // Decode and store the private key
641 void RSA::RSAImpl::SetPrivate(const byte* key, unsigned int sz)
643 TaoCrypt::Source source(key, sz);
644 privateKey_.Initialize(source);
645 publicKey_ = TaoCrypt::RSA_PublicKey(privateKey_);
649 // Set public or private key
650 RSA::RSA(const byte* key, unsigned int sz, bool publicKey)
651 : pimpl_(NEW_YS RSAImpl)
653 if (publicKey)
654 pimpl_->SetPublic(key, sz);
655 else
656 pimpl_->SetPrivate(key, sz);
659 RSA::~RSA()
661 ysDelete(pimpl_);
665 // get cipher text length, varies on key size
666 unsigned int RSA::get_cipherLength() const
668 return pimpl_->publicKey_.FixedCiphertextLength();
672 // get signautre length, varies on key size
673 unsigned int RSA::get_signatureLength() const
675 return get_cipherLength();
679 // RSA Sign message of length sz into sig
680 void RSA::sign(byte* sig, const byte* message, unsigned int sz,
681 const RandomPool& random)
683 TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_);
684 dec.SSL_Sign(message, sz, sig, random.pimpl_->RNG_);
688 // RSA Verify message of length sz against sig
689 bool RSA::verify(const byte* message, unsigned int sz, const byte* sig,
690 unsigned int)
692 TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_);
693 return enc.SSL_Verify(message, sz, sig);
697 // RSA public encrypt plain of length sz into cipher
698 void RSA::encrypt(byte* cipher, const byte* plain, unsigned int sz,
699 const RandomPool& random)
702 TaoCrypt::RSAES_Encryptor enc(pimpl_->publicKey_);
703 enc.Encrypt(plain, sz, cipher, random.pimpl_->RNG_);
707 // RSA private decrypt cipher of length sz into plain
708 void RSA::decrypt(byte* plain, const byte* cipher, unsigned int sz,
709 const RandomPool& random)
711 TaoCrypt::RSAES_Decryptor dec(pimpl_->privateKey_);
712 dec.Decrypt(cipher, sz, plain, random.pimpl_->RNG_);
716 struct Integer::IntegerImpl {
717 TaoCrypt::Integer int_;
719 IntegerImpl() {}
720 explicit IntegerImpl(const TaoCrypt::Integer& i) : int_(i) {}
723 Integer::Integer() : pimpl_(NEW_YS IntegerImpl) {}
725 Integer::~Integer() { ysDelete(pimpl_); }
729 Integer::Integer(const Integer& other) : pimpl_(NEW_YS
730 IntegerImpl(other.pimpl_->int_))
734 Integer& Integer::operator=(const Integer& that)
736 pimpl_->int_ = that.pimpl_->int_;
738 return *this;
742 void Integer::assign(const byte* num, unsigned int sz)
744 pimpl_->int_ = TaoCrypt::Integer(num, sz);
748 struct DiffieHellman::DHImpl {
749 TaoCrypt::DH dh_;
750 TaoCrypt::RandomNumberGenerator& ranPool_;
751 byte* publicKey_;
752 byte* privateKey_;
753 byte* agreedKey_;
755 DHImpl(TaoCrypt::RandomNumberGenerator& r) : ranPool_(r), publicKey_(0),
756 privateKey_(0), agreedKey_(0) {}
757 ~DHImpl()
759 ysArrayDelete(agreedKey_);
760 ysArrayDelete(privateKey_);
761 ysArrayDelete(publicKey_);
764 DHImpl(const DHImpl& that) : dh_(that.dh_), ranPool_(that.ranPool_),
765 publicKey_(0), privateKey_(0), agreedKey_(0)
767 uint length = dh_.GetByteLength();
768 AllocKeys(length, length, length);
771 void AllocKeys(unsigned int pubSz, unsigned int privSz, unsigned int agrSz)
773 publicKey_ = NEW_YS byte[pubSz];
774 privateKey_ = NEW_YS byte[privSz];
775 agreedKey_ = NEW_YS byte[agrSz];
782 // server Side DH, server's view
783 DiffieHellman::DiffieHellman(const char* file, const RandomPool& random)
784 : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
786 using namespace TaoCrypt;
787 Source source;
788 FileSource(file, source);
789 if (source.size() == 0)
790 return; // TODO add error state, and force check
791 HexDecoder hd(source);
793 pimpl_->dh_.Initialize(source);
795 uint length = pimpl_->dh_.GetByteLength();
797 pimpl_->AllocKeys(length, length, length);
798 pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
799 pimpl_->publicKey_);
804 // server Side DH, client's view
805 DiffieHellman::DiffieHellman(const byte* p, unsigned int pSz, const byte* g,
806 unsigned int gSz, const byte* pub,
807 unsigned int pubSz, const RandomPool& random)
808 : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
810 using TaoCrypt::Integer;
812 pimpl_->dh_.Initialize(Integer(p, pSz).Ref(), Integer(g, gSz).Ref());
813 pimpl_->publicKey_ = NEW_YS opaque[pubSz];
814 memcpy(pimpl_->publicKey_, pub, pubSz);
818 // Server Side DH, server's view
819 DiffieHellman::DiffieHellman(const Integer& p, const Integer& g,
820 const RandomPool& random)
821 : pimpl_(NEW_YS DHImpl(random.pimpl_->RNG_))
823 using TaoCrypt::Integer;
825 pimpl_->dh_.Initialize(p.pimpl_->int_, g.pimpl_->int_);
827 uint length = pimpl_->dh_.GetByteLength();
829 pimpl_->AllocKeys(length, length, length);
830 pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
831 pimpl_->publicKey_);
834 DiffieHellman::~DiffieHellman() { ysDelete(pimpl_); }
837 // Client side and view, use server that for p and g
838 DiffieHellman::DiffieHellman(const DiffieHellman& that)
839 : pimpl_(NEW_YS DHImpl(*that.pimpl_))
841 pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
842 pimpl_->publicKey_);
846 DiffieHellman& DiffieHellman::operator=(const DiffieHellman& that)
848 pimpl_->dh_ = that.pimpl_->dh_;
849 pimpl_->dh_.GenerateKeyPair(pimpl_->ranPool_, pimpl_->privateKey_,
850 pimpl_->publicKey_);
851 return *this;
855 void DiffieHellman::makeAgreement(const byte* other, unsigned int otherSz)
857 pimpl_->dh_.Agree(pimpl_->agreedKey_, pimpl_->privateKey_, other, otherSz);
861 uint DiffieHellman::get_agreedKeyLength() const
863 return pimpl_->dh_.GetByteLength();
867 const byte* DiffieHellman::get_agreedKey() const
869 return pimpl_->agreedKey_;
873 const byte* DiffieHellman::get_publicKey() const
875 return pimpl_->publicKey_;
879 void DiffieHellman::set_sizes(int& pSz, int& gSz, int& pubSz) const
881 using TaoCrypt::Integer;
882 Integer p = pimpl_->dh_.GetP();
883 Integer g = pimpl_->dh_.GetG();
885 pSz = p.ByteCount();
886 gSz = g.ByteCount();
887 pubSz = pimpl_->dh_.GetByteLength();
891 void DiffieHellman::get_parms(byte* bp, byte* bg, byte* bpub) const
893 using TaoCrypt::Integer;
894 Integer p = pimpl_->dh_.GetP();
895 Integer g = pimpl_->dh_.GetG();
897 p.Encode(bp, p.ByteCount());
898 g.Encode(bg, g.ByteCount());
899 memcpy(bpub, pimpl_->publicKey_, pimpl_->dh_.GetByteLength());
903 // convert PEM file to DER x509 type
904 x509* PemToDer(FILE* file, CertType type, EncryptedInfo* info)
906 using namespace TaoCrypt;
908 char header[80];
909 char footer[80];
911 if (type == Cert) {
912 strncpy(header, "-----BEGIN CERTIFICATE-----", sizeof(header));
913 strncpy(footer, "-----END CERTIFICATE-----", sizeof(footer));
914 } else {
915 strncpy(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header));
916 strncpy(footer, "-----END RSA PRIVATE KEY-----", sizeof(header));
919 long begin = -1;
920 long end = 0;
921 bool foundEnd = false;
923 char line[80];
925 while(fgets(line, sizeof(line), file))
926 if (strncmp(header, line, strlen(header)) == 0) {
927 begin = ftell(file);
928 break;
931 // remove encrypted header if there
932 if (fgets(line, sizeof(line), file)) {
933 char encHeader[] = "Proc-Type";
934 if (strncmp(encHeader, line, strlen(encHeader)) == 0 &&
935 fgets(line,sizeof(line), file)) {
937 char* start = strstr(line, "DES");
938 char* finish = strstr(line, ",");
939 if (!start)
940 start = strstr(line, "AES");
942 if (!info) return 0;
944 if ( start && finish && (start < finish)) {
945 memcpy(info->name, start, finish - start);
946 info->name[finish - start] = 0;
947 memcpy(info->iv, finish + 1, sizeof(info->iv));
949 char* newline = strstr(line, "\r");
950 if (!newline) newline = strstr(line, "\n");
951 if (newline && (newline > finish)) {
952 info->ivSz = newline - (finish + 1);
953 info->set = true;
956 // get blank line
957 if (fgets(line, sizeof(line), file))
958 begin = ftell(file);
963 while(fgets(line, sizeof(line), file))
964 if (strncmp(footer, line, strlen(footer)) == 0) {
965 foundEnd = true;
966 break;
968 else
969 end = ftell(file);
971 if (begin == -1 || !foundEnd)
972 return 0;
974 input_buffer tmp(end - begin);
975 fseek(file, begin, SEEK_SET);
976 size_t bytes = fread(tmp.get_buffer(), end - begin, 1, file);
977 if (bytes != 1)
978 return 0;
980 Source der(tmp.get_buffer(), end - begin);
981 Base64Decoder b64Dec(der);
983 uint sz = der.size();
984 mySTL::auto_ptr<x509> x(NEW_YS x509(sz));
985 memcpy(x->use_buffer(), der.get_buffer(), sz);
987 return x.release();
991 } // namespace
994 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
995 namespace yaSSL {
996 template void ysDelete<DiffieHellman::DHImpl>(DiffieHellman::DHImpl*);
997 template void ysDelete<Integer::IntegerImpl>(Integer::IntegerImpl*);
998 template void ysDelete<RSA::RSAImpl>(RSA::RSAImpl*);
999 template void ysDelete<DSS::DSSImpl>(DSS::DSSImpl*);
1000 template void ysDelete<RandomPool::RandomImpl>(RandomPool::RandomImpl*);
1001 template void ysDelete<AES::AESImpl>(AES::AESImpl*);
1002 template void ysDelete<RC4::RC4Impl>(RC4::RC4Impl*);
1003 template void ysDelete<DES_EDE::DES_EDEImpl>(DES_EDE::DES_EDEImpl*);
1004 template void ysDelete<DES::DESImpl>(DES::DESImpl*);
1005 template void ysDelete<HMAC_RMD::HMAC_RMDImpl>(HMAC_RMD::HMAC_RMDImpl*);
1006 template void ysDelete<HMAC_SHA::HMAC_SHAImpl>(HMAC_SHA::HMAC_SHAImpl*);
1007 template void ysDelete<HMAC_MD5::HMAC_MD5Impl>(HMAC_MD5::HMAC_MD5Impl*);
1008 template void ysDelete<RMD::RMDImpl>(RMD::RMDImpl*);
1009 template void ysDelete<SHA::SHAImpl>(SHA::SHAImpl*);
1010 template void ysDelete<MD5::MD5Impl>(MD5::MD5Impl*);
1012 #endif // HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1014 #endif // !USE_CRYPTOPP_LIB