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

📄 asn.cpp

📁 mysql-5.0.22.tar.gz源码包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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;        }        b = source_.next();        if (b != 0) {            source_.SetError(EXPECT_0_E);            return 0;        }    }     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_);      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_;}// process NAME, either issuer or subjectvoid CertDecoder::GetName(NameType nt){    if (source_.GetError().What()) return;    SHA    sha;    word32 length = GetSequence();  // length of all distinguished names    length += source_.get_index();    while (source_.get_index() < length) {        GetSet();        GetSequence();        byte b = source_.next();        if (b != OBJECT_IDENTIFIER) {            source_.SetError(OBJECT_ID_E);            return;        }        word32 oidSz = GetLength(source_);        byte joint[2];        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 (id == COMMON_NAME) {                char*& ptr = (nt == ISSUER) ? issuer_ : subject_;                ptr = new (tc) char[strLen + 1];                memcpy(ptr, source_.get_current(), strLen);                ptr[strLen] = 0;            }            sha.Update(source_.get_current(), strLen);            source_.advance(strLen);        }        else {            // skip            source_.advance(oidSz + 1);            word32 length = GetLength(source_);            source_.advance(length);        }    }    if (nt == ISSUER)        sha.Final(issuerHash_);    else        sha.Final(subjectHash_);}// process a Date, either BEFORE or AFTERvoid 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_);    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))        if (dt == BEFORE)            source_.SetError(BEFORE_DATE_E);        else            source_.SetError(AFTER_DATE_E);}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 digestvoid 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 elsebool CertDecoder::ValidateSignature(SignerList* signers){    assert(signers);    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;}// RSA confirmbool CertDecoder::ConfirmSignature(Source& pub){    HashType ht;    mySTL::auto_ptr<HASH> hasher(tcDelete);    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 {        source_.SetError(UNKOWN_SIG_E);        return false;    }    byte digest[SHA::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);        return enc.SSL_Verify(build.get_buffer(), build.size(), signature_);    }    else  { // DSA        // extract r and s from sequence        byte seqDecoded[DSA_SIG_SZ];        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};    int algoSz = 0;    const byte* algoName = 0;    switch (aOID) {    case SHAh:        algoSz = sizeof(shaAlgoID);        algoName = shaAlgoID;        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 integersword32 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)        if (rLen == 21) {       // zero at front, eat            source.next();            --rLen;        }        else if (rLen == 19) {  // add zero to front so 20 bytes            decoded[0] = 0;            decoded++;        }        else {            source.SetError(DSA_SZ_E);            return 0;        }    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)        if (sLen == 21) {            source.next();          // zero at front, eat            --sLen;        }        else if (sLen == 19) {            decoded[rLen] = 0;      // add zero to front so 20 bytes            decoded++;        }        else {            source.SetError(DSA_SZ_E);            return 0;        }    memcpy(decoded + rLen, source.get_buffer() + source.get_index(), sLen);    source.advance(sLen);    return 40;}} // namespace

⌨️ 快捷键说明

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