summaryrefslogtreecommitdiff
path: root/mysql/extra/yassl/taocrypt/src/asn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/extra/yassl/taocrypt/src/asn.cpp')
-rw-r--r--mysql/extra/yassl/taocrypt/src/asn.cpp1348
1 files changed, 0 insertions, 1348 deletions
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 <time.h> // 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(&ltime);
-
- 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<byte> 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<HASH> 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