⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn.cpp

📁 MySQL源码文件5.X系列, 可自已编译到服务器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*   Copyright (C) 2000-2007 MySQL AB   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_arraynamespace TaoCrypt {namespace { // locals// to the minutebool 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;    return false;}bool operator<(tm& a, tm&b){    return !(a>b);}// like atoi but only use first byteword32 btoi(byte b){    return b - 0x30;}// two byte date/time, add to valuevoid GetTime(int& value, const byte* date, int& i){    value += btoi(date[i++]) * 10;    value += btoi(date[i++]);}// Make sure before and after dates are validbool ValidateDate(const byte* date, byte format, CertDecoder::DateType dt){    tm certTime;    memset(&certTime, 0, sizeof(certTime));    int i = 0;    if (format == UTC_TIME) {        if (btoi(date[0]) >= 5)            certTime.tm_year = 1900;        else            certTime.tm_year = 2000;    }    else  { // format == GENERALIZED_TIME        certTime.tm_year += btoi(date[i++]) * 1000;        certTime.tm_year += btoi(date[i++]) * 100;    }    GetTime(certTime.tm_year, date, i);     certTime.tm_year -= 1900; // adjust    GetTime(certTime.tm_mon,  date, i);     certTime.tm_mon  -= 1;    // adjust    GetTime(certTime.tm_mday, date, i);    GetTime(certTime.tm_hour, date, i);     GetTime(certTime.tm_min,  date, i);     GetTime(certTime.tm_sec,  date, i);     assert(date[i] == 'Z');     // only Zulu supported for this profile    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 wellword32 GetLength(Source& source){    word32 length = 0;    byte b = source.next();    if (b >= LONG_LENGTH) {                word32 bytes = b & 0x7F;        while (bytes--) {            b = source.next();            length = (length << 8) | b;        }    }    else        length = b;    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){        int 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 lengthword32 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 lengthword32 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 itword32 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 Keyvoid 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 Keyvoid 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 Keyvoid RSA_Public_Decoder::Decode(RSA_PublicKey& key){    ReadHeader();    if (source_.GetError().What()) return;    // public key    key.SetModulus(GetInteger(Integer().Ref()));    key.SetPublicExponent(GetInteger(Integer().Ref()));}void RSA_Public_Decoder::ReadHeader(){    GetSequence();}// Decode a BER encoded DSA Public Keyvoid 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 Keyvoid 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),      signature_(0), verify_(!noVerify){     issuer_[0] = 0;    subject_[0] = 0;    if (decode)        Decode(signers, ct); }CertDecoder::~CertDecoder(){    tcArrayDelete(signature_);}// process certificate header, set signature offsetvoid 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 Certificatevoid 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 keyvoid 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 keyvoid CertDecoder::StoreKey(){    if (source_.GetError().What()) return;    word32 read = source_.get_index();    word32 length = GetSequence();    read = source_.get_index() - read;    length += read;    while (read--) source_.prev();    key_.SetSize(length);    key_.SetKey(source_.get_current());    source_.advance(length);}// DSA has public key after groupvoid 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;    key_.AddToEnd(source_.get_buffer() + idx, length);    }// process algo OID by summing, return itword32 CertDecoder::GetAlgoId(){    if (source_.GetError().What()) return 0;    word32 length = GetSequence();        byte b = source_.next();    if (b != OBJECT_IDENTIFIER) {        source_.SetError(OBJECT_ID_E);        return 0;    }    length = GetLength(source_);    word32 oid = 0;        while(length--)        oid += source_.next();        // just sum it up for now    if (oid != SHAwDSA && oid != DSAk) {        b = source_.next();               // should have NULL tag and 0        if (b != TAG_NULL) {            source_.SetError(TAG_NULL_E);            return 0;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -