📄 asn.cpp
字号:
/* asn.cpp * * Copyright (C) 2003 Sawtooth Consulting Ltd. * * This file is part of yaSSL. * * yaSSL 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; either version 2 of the License, or * (at your option) any later version. * * yaSSL 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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" // mySTL::auto_ptrnamespace 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(<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 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_ptr<byte> tmp(new (tc) byte[sz_ + len], tcArrayDelete); memcpy(tmp.get(), key_, sz_); memcpy(tmp.get() + sz_, data, len); byte* del = 0; mySTL::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), name_(0){ if (n) { int sz = strlen(n); name_ = new (tc) char[sz + 1]; memcpy(name_, n, sz); name_[sz] = 0; } memcpy(hash_, h, SHA::DIGEST_SIZE);}Signer::~Signer(){ tcArrayDelete(name_);}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) : BER_Decoder(s), certBegin_(0), sigIndex_(0), sigLength_(0), signature_(0), issuer_(0), subject_(0){ if (decode) Decode(signers); }CertDecoder::~CertDecoder(){ tcArrayDelete(subject_); tcArrayDelete(issuer_); 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){ 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 ( memcmp(issuerHash_, subjectHash_, SHA::DIGEST_SIZE) == 0 ) { if (!ValidateSelfSignature()) source_.SetError(SIG_CONFIRM_E); } else if (!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();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -