From 72e7f011b29998d8a3e15eb5b381ef962af5fe5b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 5 Apr 2019 10:30:58 +0300 Subject: Upgrade to 8.0.15 --- mysql/extra/yassl/taocrypt/src/asn.cpp | 1348 -------------------------------- 1 file changed, 1348 deletions(-) delete mode 100644 mysql/extra/yassl/taocrypt/src/asn.cpp (limited to 'mysql/extra/yassl/taocrypt/src/asn.cpp') diff --git a/mysql/extra/yassl/taocrypt/src/asn.cpp b/mysql/extra/yassl/taocrypt/src/asn.cpp deleted file mode 100644 index e0aef45..0000000 --- a/mysql/extra/yassl/taocrypt/src/asn.cpp +++ /dev/null @@ -1,1348 +0,0 @@ -/* - Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - MA 02110-1301 USA. -*/ - -/* asn.cpp implements ASN1 BER, PublicKey, and x509v3 decoding -*/ - -#include "runtime.hpp" -#include "asn.hpp" -#include "file.hpp" -#include "integer.hpp" -#include "rsa.hpp" -#include "dsa.hpp" -#include "dh.hpp" -#include "md5.hpp" -#include "md2.hpp" -#include "sha.hpp" -#include "coding.hpp" -#include // gmtime(); -#include "memory.hpp" // some auto_ptr don't have reset, also need auto_array - - -namespace TaoCrypt { - -// like atoi but only use first byte -word32 btoi(byte b) -{ - return b - 0x30; -} - - -// two byte date/time, add to value -void GetTime(int *value, const byte* date, int& i) -{ - *value += btoi(date[i++]) * 10; - *value += btoi(date[i++]); -} - - -bool ASN1_TIME_extract(const unsigned char* date, unsigned char format, - tm *t) -{ - int i = 0; - memset(t, 0, sizeof (tm)); - - if (format != UTC_TIME && format != GENERALIZED_TIME) - return false; - - if (format == UTC_TIME) { - if (btoi(date[0]) >= 5) - t->tm_year = 1900; - else - t->tm_year = 2000; - } - else { // format == GENERALIZED_TIME - t->tm_year += btoi(date[i++]) * 1000; - t->tm_year += btoi(date[i++]) * 100; - } - - GetTime(&t->tm_year, date, i); t->tm_year -= 1900; // adjust - GetTime(&t->tm_mon, date, i); t->tm_mon -= 1; // adjust - GetTime(&t->tm_mday, date, i); - GetTime(&t->tm_hour, date, i); - GetTime(&t->tm_min, date, i); - GetTime(&t->tm_sec, date, i); - - if (date[i] != 'Z') // only Zulu supported for this profile - return false; - return true; -} - - -namespace { // locals - - -// to the second -bool operator>(tm& a, tm& b) -{ - if (a.tm_year > b.tm_year) - return true; - - if (a.tm_year == b.tm_year && a.tm_mon > b.tm_mon) - return true; - - if (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && a.tm_mday >b.tm_mday) - return true; - - if (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && - a.tm_mday == b.tm_mday && a.tm_hour > b.tm_hour) - return true; - - if (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && - a.tm_mday == b.tm_mday && a.tm_hour == b.tm_hour && - a.tm_min > b.tm_min) - return true; - - if (a.tm_year == b.tm_year && a.tm_mon == b.tm_mon && - a.tm_mday == b.tm_mday && a.tm_hour == b.tm_hour && - a.tm_min == b.tm_min && a.tm_sec > b.tm_sec) - return true; - - return false; -} - - -bool operator<(tm& a, tm&b) -{ - return (b>a); -} - - -// Make sure before and after dates are valid -bool ValidateDate(const byte* date, byte format, CertDecoder::DateType dt) -{ - tm certTime; - - if (!ASN1_TIME_extract(date, format, &certTime)) - return false; - - time_t ltime = time(0); - tm* localTime = gmtime(<ime); - - if (dt == CertDecoder::BEFORE) { - if (*localTime < certTime) - return false; - } - else - if (*localTime > certTime) - return false; - - return true; -} - - -class BadCertificate {}; - -} // local namespace - - - -// used by Integer as well -word32 GetLength(Source& source) -{ - word32 length = 0; - - byte b = source.next(); - if (b >= LONG_LENGTH) { - word32 bytes = b & 0x7F; - - if (source.IsLeft(bytes) == false) return 0; - - while (bytes--) { - b = source.next(); - length = (length << 8) | b; - } - } - else - length = b; - - if (source.IsLeft(length) == false) return 0; - - return length; -} - - -word32 SetLength(word32 length, byte* output) -{ - word32 i = 0; - - if (length < LONG_LENGTH) - output[i++] = length; - else { - output[i++] = BytePrecision(length) | 0x80; - - for (int j = BytePrecision(length); j; --j) { - output[i] = length >> (j - 1) * 8; - i++; - } - } - return i; -} - - -PublicKey::PublicKey(const byte* k, word32 s) : key_(0), sz_(0) -{ - if (s) { - SetSize(s); - SetKey(k); - } -} - - -void PublicKey::SetSize(word32 s) -{ - sz_ = s; - key_ = NEW_TC byte[sz_]; -} - - -void PublicKey::SetKey(const byte* k) -{ - memcpy(key_, k, sz_); -} - - -void PublicKey::AddToEnd(const byte* data, word32 len) -{ - mySTL::auto_array tmp(NEW_TC byte[sz_ + len]); - - memcpy(tmp.get(), key_, sz_); - memcpy(tmp.get() + sz_, data, len); - - byte* del = 0; - STL::swap(del, key_); - tcArrayDelete(del); - - key_ = tmp.release(); - sz_ += len; -} - - -Signer::Signer(const byte* k, word32 kSz, const char* n, const byte* h) - : key_(k, kSz) -{ - size_t sz = strlen(n); - memcpy(name_, n, sz); - name_[sz] = 0; - - memcpy(hash_, h, SHA::DIGEST_SIZE); -} - -Signer::~Signer() -{ -} - - -Error BER_Decoder::GetError() -{ - return source_.GetError(); -} - - -Integer& BER_Decoder::GetInteger(Integer& integer) -{ - if (!source_.GetError().What()) - integer.Decode(source_); - return integer; -} - - -// Read a Sequence, return length -word32 BER_Decoder::GetSequence() -{ - if (source_.GetError().What()) return 0; - - byte b = source_.next(); - if (b != (SEQUENCE | CONSTRUCTED)) { - source_.SetError(SEQUENCE_E); - return 0; - } - - return GetLength(source_); -} - - -// Read a Sequence, return length -word32 BER_Decoder::GetSet() -{ - if (source_.GetError().What()) return 0; - - byte b = source_.next(); - if (b != (SET | CONSTRUCTED)) { - source_.SetError(SET_E); - return 0; - } - - return GetLength(source_); -} - - -// Read Version, return it -word32 BER_Decoder::GetVersion() -{ - if (source_.GetError().What()) return 0; - - byte b = source_.next(); - if (b != INTEGER) { - source_.SetError(INTEGER_E); - return 0; - } - - b = source_.next(); - if (b != 0x01) { - source_.SetError(VERSION_E); - return 0; - } - - return source_.next(); -} - - -// Read ExplicitVersion, return it or 0 if not there (not an error) -word32 BER_Decoder::GetExplicitVersion() -{ - if (source_.GetError().What()) return 0; - - byte b = source_.next(); - - if (b == (CONTEXT_SPECIFIC | CONSTRUCTED)) { // not an error if not here - source_.next(); - return GetVersion(); - } - else - source_.prev(); // put back - - return 0; -} - - -// Decode a BER encoded RSA Private Key -void RSA_Private_Decoder::Decode(RSA_PrivateKey& key) -{ - ReadHeader(); - if (source_.GetError().What()) return; - // public - key.SetModulus(GetInteger(Integer().Ref())); - key.SetPublicExponent(GetInteger(Integer().Ref())); - - // private - key.SetPrivateExponent(GetInteger(Integer().Ref())); - key.SetPrime1(GetInteger(Integer().Ref())); - key.SetPrime2(GetInteger(Integer().Ref())); - key.SetModPrime1PrivateExponent(GetInteger(Integer().Ref())); - key.SetModPrime2PrivateExponent(GetInteger(Integer().Ref())); - key.SetMultiplicativeInverseOfPrime2ModPrime1(GetInteger(Integer().Ref())); -} - - -void RSA_Private_Decoder::ReadHeader() -{ - GetSequence(); - GetVersion(); -} - - -// Decode a BER encoded DSA Private Key -void DSA_Private_Decoder::Decode(DSA_PrivateKey& key) -{ - ReadHeader(); - if (source_.GetError().What()) return; - // group parameters - key.SetModulus(GetInteger(Integer().Ref())); - key.SetSubGroupOrder(GetInteger(Integer().Ref())); - key.SetSubGroupGenerator(GetInteger(Integer().Ref())); - - // key - key.SetPublicPart(GetInteger(Integer().Ref())); - key.SetPrivatePart(GetInteger(Integer().Ref())); -} - - -void DSA_Private_Decoder::ReadHeader() -{ - GetSequence(); - GetVersion(); -} - - -// Decode a BER encoded RSA Public Key -void RSA_Public_Decoder::Decode(RSA_PublicKey& key) -{ - ReadHeader(); - if (source_.GetError().What()) return; - - ReadHeaderOpenSSL(); // may or may not be - if (source_.GetError().What()) return; - - // public key - key.SetModulus(GetInteger(Integer().Ref())); - key.SetPublicExponent(GetInteger(Integer().Ref())); -} - - -// Read OpenSSL format public header -void RSA_Public_Decoder::ReadHeaderOpenSSL() -{ - byte b = source_.next(); // peek - source_.prev(); - - if (b != INTEGER) { // have OpenSSL public format - GetSequence(); - b = source_.next(); - if (b != OBJECT_IDENTIFIER) { - source_.SetError(OBJECT_ID_E); - return; - } - - word32 len = GetLength(source_); - source_.advance(len); - - b = source_.next(); - if (b == TAG_NULL) { // could have NULL tag and 0 terminator, may not - b = source_.next(); - if (b != 0) { - source_.SetError(EXPECT_0_E); - return; - } - } - else - source_.prev(); // put back - - b = source_.next(); - if (b != BIT_STRING) { - source_.SetError(BIT_STR_E); - return; - } - - len = GetLength(source_); - b = source_.next(); - if (b != 0) // could have 0 - source_.prev(); // put back - - GetSequence(); - } -} - - -void RSA_Public_Decoder::ReadHeader() -{ - GetSequence(); -} - - -// Decode a BER encoded DSA Public Key -void DSA_Public_Decoder::Decode(DSA_PublicKey& key) -{ - ReadHeader(); - if (source_.GetError().What()) return; - - // group parameters - key.SetModulus(GetInteger(Integer().Ref())); - key.SetSubGroupOrder(GetInteger(Integer().Ref())); - key.SetSubGroupGenerator(GetInteger(Integer().Ref())); - - // key - key.SetPublicPart(GetInteger(Integer().Ref())); -} - - -void DSA_Public_Decoder::ReadHeader() -{ - GetSequence(); -} - - -void DH_Decoder::ReadHeader() -{ - GetSequence(); -} - - -// Decode a BER encoded Diffie-Hellman Key -void DH_Decoder::Decode(DH& key) -{ - ReadHeader(); - if (source_.GetError().What()) return; - - // group parms - key.SetP(GetInteger(Integer().Ref())); - key.SetG(GetInteger(Integer().Ref())); -} - - -CertDecoder::CertDecoder(Source& s, bool decode, SignerList* signers, - bool noVerify, CertType ct) - : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), subCnPos_(-1), - subCnLen_(0), issCnPos_(-1), issCnLen_(0), signature_(0), - verify_(!noVerify) -{ - issuer_[0] = 0; - subject_[0] = 0; - - if (decode) - Decode(signers, ct); - -} - - -CertDecoder::~CertDecoder() -{ - tcArrayDelete(signature_); -} - - -// process certificate header, set signature offset -void CertDecoder::ReadHeader() -{ - if (source_.GetError().What()) return; - - GetSequence(); // total - certBegin_ = source_.get_index(); - - sigIndex_ = GetSequence(); // this cert - sigIndex_ += source_.get_index(); - - GetExplicitVersion(); // version - GetInteger(Integer().Ref()); // serial number -} - - -// Decode a x509v3 Certificate -void CertDecoder::Decode(SignerList* signers, CertType ct) -{ - if (source_.GetError().What()) return; - DecodeToKey(); - if (source_.GetError().What()) return; - - if (source_.get_index() != sigIndex_) - source_.set_index(sigIndex_); - - word32 confirmOID = GetAlgoId(); - GetSignature(); - if (source_.GetError().What()) return; - - if ( confirmOID != signatureOID_ ) { - source_.SetError(SIG_OID_E); - return; - } - - if (ct != CA && verify_ && !ValidateSignature(signers)) - source_.SetError(SIG_OTHER_E); -} - - -void CertDecoder::DecodeToKey() -{ - ReadHeader(); - signatureOID_ = GetAlgoId(); - GetName(ISSUER); - GetValidity(); - GetName(SUBJECT); - GetKey(); -} - - -// Read public key -void CertDecoder::GetKey() -{ - if (source_.GetError().What()) return; - - GetSequence(); - keyOID_ = GetAlgoId(); - - if (keyOID_ == RSAk) { - byte b = source_.next(); - if (b != BIT_STRING) { - source_.SetError(BIT_STR_E); - return; - } - b = source_.next(); // length, future - b = source_.next(); - while(b != 0) - b = source_.next(); - } - else if (keyOID_ == DSAk) - ; // do nothing - else { - source_.SetError(UNKNOWN_OID_E); - return; - } - - StoreKey(); - if (keyOID_ == DSAk) - AddDSA(); -} - - -// Save public key -void CertDecoder::StoreKey() -{ - if (source_.GetError().What()) return; - - word32 read = source_.get_index(); - word32 length = GetSequence(); - - read = source_.get_index() - read; - length += read; - - if (source_.GetError().What()) return; - while (read--) source_.prev(); - - if (source_.IsLeft(length) == false) return; - key_.SetSize(length); - key_.SetKey(source_.get_current()); - source_.advance(length); -} - - -// DSA has public key after group -void CertDecoder::AddDSA() -{ - if (source_.GetError().What()) return; - - byte b = source_.next(); - if (b != BIT_STRING) { - source_.SetError(BIT_STR_E); - return; - } - b = source_.next(); // length, future - b = source_.next(); - while(b != 0) - b = source_.next(); - - word32 idx = source_.get_index(); - b = source_.next(); - if (b != INTEGER) { - source_.SetError(INTEGER_E); - return; - } - - word32 length = GetLength(source_); - length += source_.get_index() - idx; - - if (source_.IsLeft(length) == false) return; - - key_.AddToEnd(source_.get_buffer() + idx, length); -} - - -// process algo OID by summing, return it -word32 CertDecoder::GetAlgoId() -{ - if (source_.GetError().What()) return 0; - word32 length = GetSequence(); - - if (source_.GetError().What()) return 0; - - byte b = source_.next(); - if (b != OBJECT_IDENTIFIER) { - source_.SetError(OBJECT_ID_E); - return 0; - } - - length = GetLength(source_); - if (source_.IsLeft(length) == false) return 0; - - word32 oid = 0; - while(length--) - oid += source_.next(); // just sum it up for now - - // could have NULL tag and 0 terminator, but may not - b = source_.next(); - if (b == TAG_NULL) { - b = source_.next(); - if (b != 0) { - source_.SetError(EXPECT_0_E); - return 0; - } - } - else - // go back, didn't have it - b = source_.prev(); - - return oid; -} - - -// read cert signature, store in signature_ -word32 CertDecoder::GetSignature() -{ - if (source_.GetError().What()) return 0; - byte b = source_.next(); - - if (b != BIT_STRING) { - source_.SetError(BIT_STR_E); - return 0; - } - - sigLength_ = GetLength(source_); - if (sigLength_ <= 1 || source_.IsLeft(sigLength_) == false) { - source_.SetError(CONTENT_E); - return 0; - } - - b = source_.next(); - if (b != 0) { - source_.SetError(EXPECT_0_E); - return 0; - } - sigLength_--; - - signature_ = NEW_TC byte[sigLength_]; - memcpy(signature_, source_.get_current(), sigLength_); - source_.advance(sigLength_); - - return sigLength_; -} - - -// read cert digest, store in signature_ -word32 CertDecoder::GetDigest() -{ - if (source_.GetError().What()) return 0; - byte b = source_.next(); - - if (b != OCTET_STRING) { - source_.SetError(OCTET_STR_E); - return 0; - } - - sigLength_ = GetLength(source_); - - signature_ = NEW_TC byte[sigLength_]; - memcpy(signature_, source_.get_current(), sigLength_); - source_.advance(sigLength_); - - return sigLength_; -} - - -// memory length checked add tag to buffer -char* CertDecoder::AddTag(char* ptr, const char* buf_end, const char* tag_name, - word32 tag_name_length, word32 tag_value_length) -{ - if (ptr + tag_name_length + tag_value_length > buf_end) { - source_.SetError(CONTENT_E); - return 0; - } - - memcpy(ptr, tag_name, tag_name_length); - ptr += tag_name_length; - - memcpy(ptr, source_.get_current(), tag_value_length); - ptr += tag_value_length; - - return ptr; -} - - -// process NAME, either issuer or subject -void CertDecoder::GetName(NameType nt) -{ - if (source_.GetError().What()) return; - - SHA sha; - word32 length = GetSequence(); // length of all distinguished names - - if (length >= ASN_NAME_MAX) - return; - if (source_.IsLeft(length) == false) return; - length += source_.get_index(); - - char* ptr; - char* buf_end; - - if (nt == ISSUER) { - ptr = issuer_; - buf_end = ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0 - } - else { - ptr = subject_; - buf_end = ptr + sizeof(subject_) - 1; // 1 byte for trailing 0 - } - - while (source_.get_index() < length) { - GetSet(); - if (source_.GetError().What() == SET_E) { - source_.SetError(NO_ERROR_E); // extensions may only have sequence - source_.prev(); - } - GetSequence(); - - byte b = source_.next(); - if (b != OBJECT_IDENTIFIER) { - source_.SetError(OBJECT_ID_E); - return; - } - - word32 oidSz = GetLength(source_); - if (source_.IsLeft(oidSz) == false) return; - - byte joint[2]; - if (source_.IsLeft(sizeof(joint)) == false) return; - memcpy(joint, source_.get_current(), sizeof(joint)); - - // v1 name types - if (joint[0] == 0x55 && joint[1] == 0x04) { - source_.advance(2); - byte id = source_.next(); - b = source_.next(); // strType - word32 strLen = GetLength(source_); - - if (source_.IsLeft(strLen) == false) return; - - switch (id) { - case COMMON_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen))) - return; - if (nt == ISSUER) { - issCnPos_ = (int)(ptr - strLen - issuer_); - issCnLen_ = (int)strLen; - } else { - subCnPos_ = (int)(ptr - strLen - subject_); - subCnLen_ = (int)strLen; - } - break; - case SUR_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen))) - return; - break; - case COUNTRY_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/C=", 3, strLen))) - return; - break; - case LOCALITY_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/L=", 3, strLen))) - return; - break; - case STATE_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/ST=", 4, strLen))) - return; - break; - case ORG_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/O=", 3, strLen))) - return; - break; - case ORGUNIT_NAME: - if (!(ptr = AddTag(ptr, buf_end, "/OU=", 4, strLen))) - return; - break; - } - - sha.Update(source_.get_current(), strLen); - source_.advance(strLen); - } - else { - bool email = false; - if (joint[0] == 0x2a && joint[1] == 0x86) // email id hdr - email = true; - - source_.advance(oidSz + 1); - word32 length = GetLength(source_); - if (source_.IsLeft(length) == false) return; - - if (email) { - if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) - return; - } - - source_.advance(length); - } - } - - *ptr = 0; - - if (nt == ISSUER) - sha.Final(issuerHash_); - else - sha.Final(subjectHash_); -} - - -// process a Date, either BEFORE or AFTER -void CertDecoder::GetDate(DateType dt) -{ - if (source_.GetError().What()) return; - - byte b = source_.next(); - if (b != UTC_TIME && b != GENERALIZED_TIME) { - source_.SetError(TIME_E); - return; - } - - word32 length = GetLength(source_); - if (source_.IsLeft(length) == false) return; - - byte date[MAX_DATE_SZ]; - if (length > MAX_DATE_SZ || length < MIN_DATE_SZ) { - source_.SetError(DATE_SZ_E); - return; - } - - memcpy(date, source_.get_current(), length); - source_.advance(length); - - if (!ValidateDate(date, b, dt) && verify_) { - if (dt == BEFORE) - source_.SetError(BEFORE_DATE_E); - else - source_.SetError(AFTER_DATE_E); - } - - // save for later use - if (dt == BEFORE) { - memcpy(beforeDate_, date, length); - beforeDate_[length] = 0; - beforeDateType_= b; - } - else { // after - memcpy(afterDate_, date, length); - afterDate_[length] = 0; - afterDateType_= b; - } -} - - -void CertDecoder::GetValidity() -{ - if (source_.GetError().What()) return; - - GetSequence(); - GetDate(BEFORE); - GetDate(AFTER); -} - - -bool CertDecoder::ValidateSelfSignature() -{ - Source pub(key_.GetKey(), key_.size()); - return ConfirmSignature(pub); -} - - -// extract compare signature hash from plain and place into digest -void CertDecoder::GetCompareHash(const byte* plain, word32 sz, byte* digest, - word32 digSz) -{ - if (source_.GetError().What()) return; - - Source s(plain, sz); - CertDecoder dec(s, false); - - dec.GetSequence(); - dec.GetAlgoId(); - dec.GetDigest(); - - if (dec.sigLength_ > digSz) { - source_.SetError(SIG_LEN_E); - return; - } - - memcpy(digest, dec.signature_, dec.sigLength_); -} - - -// validate signature signed by someone else -bool CertDecoder::ValidateSignature(SignerList* signers) -{ - if (!signers) - return false; - - SignerList::iterator first = signers->begin(); - SignerList::iterator last = signers->end(); - - while (first != last) { - if ( memcmp(issuerHash_, (*first)->GetHash(), SHA::DIGEST_SIZE) == 0) { - - const PublicKey& iKey = (*first)->GetPublicKey(); - Source pub(iKey.GetKey(), iKey.size()); - return ConfirmSignature(pub); - } - ++first; - } - return false; -} - - -// confirm certificate signature -bool CertDecoder::ConfirmSignature(Source& pub) -{ - HashType ht; - mySTL::auto_ptr hasher; - - if (signatureOID_ == MD5wRSA) { - hasher.reset(NEW_TC MD5); - ht = MD5h; - } - else if (signatureOID_ == MD2wRSA) { - hasher.reset(NEW_TC MD2); - ht = MD2h; - } - else if (signatureOID_ == SHAwRSA || signatureOID_ == SHAwDSA) { - hasher.reset(NEW_TC SHA); - ht = SHAh; - } - else if (signatureOID_ == SHA256wRSA || signatureOID_ == SHA256wDSA) { - hasher.reset(NEW_TC SHA256); - ht = SHA256h; - } -#ifdef WORD64_AVAILABLE - else if (signatureOID_ == SHA384wRSA) { - hasher.reset(NEW_TC SHA384); - ht = SHA384h; - } - else if (signatureOID_ == SHA512wRSA) { - hasher.reset(NEW_TC SHA512); - ht = SHA512h; - } -#endif - else { - source_.SetError(UNKOWN_SIG_E); - return false; - } - - byte digest[MAX_SHA2_DIGEST_SIZE]; // largest size - - hasher->Update(source_.get_buffer() + certBegin_, sigIndex_ - certBegin_); - hasher->Final(digest); - - if (keyOID_ == RSAk) { - // put in ASN.1 signature format - Source build; - Signature_Encoder(digest, hasher->getDigestSize(), ht, build); - - RSA_PublicKey pubKey(pub); - RSAES_Encryptor enc(pubKey); - - if (pubKey.FixedCiphertextLength() != sigLength_) { - source_.SetError(SIG_LEN_E); - return false; - } - - return enc.SSL_Verify(build.get_buffer(), build.size(), signature_); - } - else { // DSA - // extract r and s from sequence - byte seqDecoded[DSA_SIG_SZ]; - memset(seqDecoded, 0, sizeof(seqDecoded)); - DecodeDSA_Signature(seqDecoded, signature_, sigLength_); - - DSA_PublicKey pubKey(pub); - DSA_Verifier ver(pubKey); - - return ver.Verify(digest, seqDecoded); - } -} - - -Signature_Encoder::Signature_Encoder(const byte* dig, word32 digSz, - HashType digOID, Source& source) -{ - // build bottom up - - // Digest - byte digArray[MAX_DIGEST_SZ]; - word32 digestSz = SetDigest(dig, digSz, digArray); - - // AlgoID - byte algoArray[MAX_ALGO_SZ]; - word32 algoSz = SetAlgoID(digOID, algoArray); - - // Sequence - byte seqArray[MAX_SEQ_SZ]; - word32 seqSz = SetSequence(digestSz + algoSz, seqArray); - - source.grow(seqSz + algoSz + digestSz); // make sure enough room - source.add(seqArray, seqSz); - source.add(algoArray, algoSz); - source.add(digArray, digestSz); -} - - - -word32 Signature_Encoder::SetDigest(const byte* d, word32 dSz, byte* output) -{ - output[0] = OCTET_STRING; - output[1] = dSz; - memcpy(&output[2], d, dSz); - - return dSz + 2; -} - - - -word32 DER_Encoder::SetAlgoID(HashType aOID, byte* output) -{ - // adding TAG_NULL and 0 to end - static const byte shaAlgoID[] = { 0x2b, 0x0e, 0x03, 0x02, 0x1a, - 0x05, 0x00 }; - static const byte md5AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x02, 0x05, 0x05, 0x00 }; - static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x02, 0x02, 0x05, 0x00}; - static const byte sha256AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x01, 0x05, 0x00 }; - static const byte sha384AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x02, 0x05, 0x00 }; - static const byte sha512AlgoID[] = { 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, - 0x04, 0x02, 0x03, 0x05, 0x00 }; - int algoSz = 0; - const byte* algoName = 0; - - switch (aOID) { - case SHAh: - algoSz = sizeof(shaAlgoID); - algoName = shaAlgoID; - break; - - case SHA256h: - algoSz = sizeof(sha256AlgoID); - algoName = sha256AlgoID; - break; - - case SHA384h: - algoSz = sizeof(sha384AlgoID); - algoName = sha384AlgoID; - break; - - case SHA512h: - algoSz = sizeof(sha512AlgoID); - algoName = sha512AlgoID; - break; - - case MD2h: - algoSz = sizeof(md2AlgoID); - algoName = md2AlgoID; - break; - - case MD5h: - algoSz = sizeof(md5AlgoID); - algoName = md5AlgoID; - break; - - default: - error_.SetError(UNKOWN_HASH_E); - return 0; - } - - - byte ID_Length[MAX_LENGTH_SZ]; - word32 idSz = SetLength(algoSz - 2, ID_Length); // don't include TAG_NULL/0 - - byte seqArray[MAX_SEQ_SZ + 1]; // add object_id to end - word32 seqSz = SetSequence(idSz + algoSz + 1, seqArray); - seqArray[seqSz++] = OBJECT_IDENTIFIER; - - memcpy(output, seqArray, seqSz); - memcpy(output + seqSz, ID_Length, idSz); - memcpy(output + seqSz + idSz, algoName, algoSz); - - return seqSz + idSz + algoSz; -} - - -word32 SetSequence(word32 len, byte* output) -{ - - output[0] = SEQUENCE | CONSTRUCTED; - return SetLength(len, output + 1) + 1; -} - - -word32 EncodeDSA_Signature(const byte* signature, byte* output) -{ - Integer r(signature, 20); - Integer s(signature + 20, 20); - - return EncodeDSA_Signature(r, s, output); -} - - -word32 EncodeDSA_Signature(const Integer& r, const Integer& s, byte* output) -{ - word32 rSz = r.ByteCount(); - word32 sSz = s.ByteCount(); - - byte rLen[MAX_LENGTH_SZ + 1]; - byte sLen[MAX_LENGTH_SZ + 1]; - - rLen[0] = INTEGER; - sLen[0] = INTEGER; - - word32 rLenSz = SetLength(rSz, &rLen[1]) + 1; - word32 sLenSz = SetLength(sSz, &sLen[1]) + 1; - - byte seqArray[MAX_SEQ_SZ]; - - word32 seqSz = SetSequence(rLenSz + rSz + sLenSz + sSz, seqArray); - - // seq - memcpy(output, seqArray, seqSz); - // r - memcpy(output + seqSz, rLen, rLenSz); - r.Encode(output + seqSz + rLenSz, rSz); - // s - memcpy(output + seqSz + rLenSz + rSz, sLen, sLenSz); - s.Encode(output + seqSz + rLenSz + rSz + sLenSz, sSz); - - return seqSz + rLenSz + rSz + sLenSz + sSz; -} - - -// put sequence encoded dsa signature into decoded in 2 20 byte integers -word32 DecodeDSA_Signature(byte* decoded, const byte* encoded, word32 sz) -{ - Source source(encoded, sz); - - if (source.next() != (SEQUENCE | CONSTRUCTED)) { - source.SetError(SEQUENCE_E); - return 0; - } - - GetLength(source); // total - - // r - if (source.next() != INTEGER) { - source.SetError(INTEGER_E); - return 0; - } - word32 rLen = GetLength(source); - if (rLen != 20) { - while (rLen > 20 && source.remaining() > 0) { // zero's at front, eat - source.next(); - --rLen; - } - if (rLen < 20) { // add zero's to front so 20 bytes - word32 tmpLen = rLen; - while (tmpLen < 20) { - decoded[0] = 0; - decoded++; - tmpLen++; - } - } - } - memcpy(decoded, source.get_buffer() + source.get_index(), rLen); - source.advance(rLen); - - // s - if (source.next() != INTEGER) { - source.SetError(INTEGER_E); - return 0; - } - word32 sLen = GetLength(source); - if (sLen != 20) { - while (sLen > 20 && source.remaining() > 0) { - source.next(); // zero's at front, eat - --sLen; - } - if (sLen < 20) { // add zero's to front so 20 bytes - word32 tmpLen = sLen; - while (tmpLen < 20) { - decoded[rLen] = 0; - decoded++; - tmpLen++; - } - } - } - memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen); - source.advance(sLen); - - return 40; -} - - -/* -// Get Cert in PEM format from BEGIN to END -int GetCert(Source& source) -{ - char header[] = "-----BEGIN CERTIFICATE-----"; - char footer[] = "-----END CERTIFICATE-----"; - - char* begin = strstr((char*)source.get_buffer(), header); - char* end = strstr((char*)source.get_buffer(), footer); - - if (!begin || !end || begin >= end) return -1; - - end += strlen(footer); - if (*end == '\r') end++; - - Source tmp((byte*)begin, end - begin + 1); - source.Swap(tmp); - - return 0; -} - - - -// Decode a BER encoded PKCS12 structure -void PKCS12_Decoder::Decode() -{ - ReadHeader(); - if (source_.GetError().What()) return; - - // Get AuthSafe - - GetSequence(); - - // get object id - byte obj_id = source_.next(); - if (obj_id != OBJECT_IDENTIFIER) { - source_.SetError(OBJECT_ID_E); - return; - } - - word32 length = GetLength(source_); - - word32 algo_sum = 0; - while (length--) - algo_sum += source_.next(); - - - - - - - // Get MacData optional - // mac digestInfo like certdecoder::getdigest? - // macsalt octet string - // iter integer - -} - - -void PKCS12_Decoder::ReadHeader() -{ - // Gets Version - GetSequence(); - GetVersion(); -} - - -// Get Cert in PEM format from pkcs12 file -int GetPKCS_Cert(const char* password, Source& source) -{ - PKCS12_Decoder pkcs12(source); - pkcs12.Decode(); - - return 0; -} -*/ - - - -} // namespace -- cgit v1.1