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

📄 yassl_imp.cpp

📁 一个不错的关于手机模块程序This page contains everything that has changed in the history of DC++. Read this to fin
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* yassl_imp.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
 */

/*  yaSSL source implements all SSL.v3 secification structures.
 */

#include "runtime.hpp"
#include "yassl_int.hpp"
#include "handshake.hpp"

#include "asn.hpp"  // provide crypto wrapper??



namespace yaSSL {


namespace { // locals

bool isTLS(ProtocolVersion pv)
{
    if (pv.major_ >= 3 && pv.minor_ >= 1)
        return true;

    return false;
}


}  // namespace (locals)


void hashHandShake(SSL&, const input_buffer&, uint);


ProtocolVersion::ProtocolVersion(uint8 maj, uint8 min) 
    : major_(maj), minor_(min) 
{}


// construct key exchange with known ssl parms
void ClientKeyExchange::createKey(SSL& ssl)
{
    const ClientKeyFactory& ckf = ssl.getFactory().getClientKey();
    client_key_ = ckf.CreateObject(ssl.getSecurity().get_parms().kea_);

    if (!client_key_)
        ssl.SetError(factory_error);
}


// construct key exchange with known ssl parms
void ServerKeyExchange::createKey(SSL& ssl)
{
    const ServerKeyFactory& skf = ssl.getFactory().getServerKey();
    server_key_ = skf.CreateObject(ssl.getSecurity().get_parms().kea_);

    if (!server_key_)
        ssl.SetError(factory_error);
}


// build/set PreMaster secret and encrypt, client side
void EncryptedPreMasterSecret::build(SSL& ssl)
{
    opaque tmp[SECRET_LEN];
    memset(tmp, 0, sizeof(tmp));
    ssl.getCrypto().get_random().Fill(tmp, SECRET_LEN);
    ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
    tmp[0] = pv.major_;
    tmp[1] = pv.minor_;
    ssl.set_preMaster(tmp, SECRET_LEN);

    const CertManager& cert = ssl.getCrypto().get_certManager();
    RSA rsa(cert.get_peerKey(), cert.get_peerKeyLength());
    bool tls = ssl.isTLS();     // if TLS, put length for encrypted data
    alloc(rsa.get_cipherLength() + (tls ? 2 : 0));
    byte* holder = secret_;
    if (tls) {
        byte len[2];
        c16toa(rsa.get_cipherLength(), len);
        memcpy(secret_, len, sizeof(len));
        holder += 2;
    }
    rsa.encrypt(holder, tmp, SECRET_LEN, ssl.getCrypto().get_random());
}


// build/set premaster and Client Public key, client side
void ClientDiffieHellmanPublic::build(SSL& ssl)
{
    DiffieHellman& dhServer = ssl.useCrypto().use_dh();
    DiffieHellman  dhClient(dhServer);

    uint keyLength = dhClient.get_agreedKeyLength(); // pub and agree same

    alloc(keyLength, true);
    dhClient.makeAgreement(dhServer.get_publicKey(), keyLength);
    c16toa(keyLength, Yc_);
    memcpy(Yc_ + KEY_OFFSET, dhClient.get_publicKey(), keyLength);

    // because of encoding first byte might be zero, don't use it for preMaster
    if (*dhClient.get_agreedKey() == 0) 
        ssl.set_preMaster(dhClient.get_agreedKey() + 1, keyLength - 1);
    else
        ssl.set_preMaster(dhClient.get_agreedKey(), keyLength);
}


// build server exhange, server side
void DH_Server::build(SSL& ssl)
{
    DiffieHellman& dhServer = ssl.useCrypto().use_dh();

    int pSz, gSz, pubSz;
    dhServer.set_sizes(pSz, gSz, pubSz);
    dhServer.get_parms(parms_.alloc_p(pSz), parms_.alloc_g(gSz),
                       parms_.alloc_pub(pubSz));

    short sigSz = 0;
    mySTL::auto_ptr<Auth> auth(ysDelete);
    const CertManager& cert = ssl.getCrypto().get_certManager();
    
    if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
        auth.reset(NEW_YS RSA(cert.get_privateKey(),
                   cert.get_privateKeyLength(), false));
    else {
        auth.reset(NEW_YS DSS(cert.get_privateKey(),
                   cert.get_privateKeyLength(), false));
        sigSz += DSS_ENCODED_EXTRA;
    }
    

    sigSz += auth->get_signatureLength();


    length_ = 8; // pLen + gLen + YsLen + SigLen
    length_ += pSz + gSz + pubSz + sigSz;

    output_buffer tmp(length_);
    byte len[2];
    // P
    c16toa(pSz, len);
    tmp.write(len, sizeof(len));
    tmp.write(parms_.get_p(), pSz);
    // G
    c16toa(gSz, len);
    tmp.write(len, sizeof(len));
    tmp.write(parms_.get_g(), gSz);
    // Ys
    c16toa(pubSz, len);
    tmp.write(len, sizeof(len));
    tmp.write(parms_.get_pub(), pubSz);

    // Sig
    byte hash[FINISHED_SZ];
    MD5  md5;
    SHA  sha;
    signature_ = NEW_YS byte[sigSz];

    const Connection& conn = ssl.getSecurity().get_connection();
    // md5
    md5.update(conn.client_random_, RAN_LEN);
    md5.update(conn.server_random_, RAN_LEN);
    md5.update(tmp.get_buffer(), tmp.get_size());
    md5.get_digest(hash);

    // sha
    sha.update(conn.client_random_, RAN_LEN);
    sha.update(conn.server_random_, RAN_LEN);
    sha.update(tmp.get_buffer(), tmp.get_size());
    sha.get_digest(&hash[MD5_LEN]);

    if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
        auth->sign(signature_, hash, sizeof(hash),
                   ssl.getCrypto().get_random());
    else {
        auth->sign(signature_, &hash[MD5_LEN], SHA_LEN,
                   ssl.getCrypto().get_random());
        byte encoded[DSS_SIG_SZ + DSS_ENCODED_EXTRA];
        TaoCrypt::EncodeDSA_Signature(signature_, encoded);
        memcpy(signature_, encoded, sizeof(encoded));
    }

    c16toa(sigSz, len);
    tmp.write(len, sizeof(len));
    tmp.write(signature_, sigSz);

    // key message
    keyMessage_ = NEW_YS opaque[length_];
    memcpy(keyMessage_, tmp.get_buffer(), tmp.get_size());
}


// read PreMaster secret and decrypt, server side
void EncryptedPreMasterSecret::read(SSL& ssl, input_buffer& input)
{
    const CertManager& cert = ssl.getCrypto().get_certManager();
    RSA rsa(cert.get_privateKey(), cert.get_privateKeyLength(), false);
    uint16 cipherLen = rsa.get_cipherLength();
    if (ssl.isTLS()) {
        byte len[2];
        input.read(len, sizeof(len));
        ato16(len, cipherLen);
    }
    alloc(cipherLen);
    input.read(secret_, length_);

    opaque preMasterSecret[SECRET_LEN];
    rsa.decrypt(preMasterSecret, secret_, length_, 
                ssl.getCrypto().get_random());

    ssl.set_preMaster(preMasterSecret, SECRET_LEN);
    ssl.makeMasterSecret();
}


EncryptedPreMasterSecret::EncryptedPreMasterSecret()
    : secret_(0), length_(0)
{}


EncryptedPreMasterSecret::~EncryptedPreMasterSecret()
{
    ysArrayDelete(secret_);
}


int EncryptedPreMasterSecret::get_length() const
{
    return length_;
}


opaque* EncryptedPreMasterSecret::get_clientKey() const
{
    return secret_;
}


void EncryptedPreMasterSecret::alloc(int sz)
{
    length_ = sz;
    secret_ = NEW_YS opaque[sz];
}


// read client's public key, server side
void ClientDiffieHellmanPublic::read(SSL& ssl, input_buffer& input)
{
    DiffieHellman& dh = ssl.useCrypto().use_dh();

    uint16 keyLength;
    byte tmp[2];
    tmp[0] = input[AUTO];
    tmp[1] = input[AUTO];
    ato16(tmp, keyLength);

    alloc(keyLength);
    input.read(Yc_, keyLength);
    dh.makeAgreement(Yc_, keyLength); 

    // because of encoding, first byte might be 0, don't use for preMaster 
    if (*dh.get_agreedKey() == 0) 
        ssl.set_preMaster(dh.get_agreedKey() + 1, dh.get_agreedKeyLength() - 1);
    else
        ssl.set_preMaster(dh.get_agreedKey(), dh.get_agreedKeyLength());
    ssl.makeMasterSecret();
}


ClientDiffieHellmanPublic::ClientDiffieHellmanPublic()
    : length_(0), Yc_(0)
{}


ClientDiffieHellmanPublic::~ClientDiffieHellmanPublic()
{
    ysArrayDelete(Yc_);
}


int ClientDiffieHellmanPublic::get_length() const
{
    return length_;
}


opaque* ClientDiffieHellmanPublic::get_clientKey() const
{
    return Yc_;
}


void ClientDiffieHellmanPublic::alloc(int sz, bool offset) 
{
    length_ = sz + (offset ? KEY_OFFSET : 0); 
    Yc_ = NEW_YS opaque[length_];
}


// read server's p, g, public key and sig, client side
void DH_Server::read(SSL& ssl, input_buffer& input)
{
    uint16 length, messageTotal = 6; // pSz + gSz + pubSz
    byte tmp[2];

    // p
    tmp[0] = input[AUTO];
    tmp[1] = input[AUTO];
    ato16(tmp, length);
    messageTotal += length;

    input.read(parms_.alloc_p(length), length);

    // g
    tmp[0] = input[AUTO];
    tmp[1] = input[AUTO];
    ato16(tmp, length);
    messageTotal += length;

    input.read(parms_.alloc_g(length), length);

    // pub
    tmp[0] = input[AUTO];
    tmp[1] = input[AUTO];
    ato16(tmp, length);
    messageTotal += length;

    input.read(parms_.alloc_pub(length), length);

    // save message for hash verify
    input_buffer message(messageTotal);
    input.set_current(input.get_current() - messageTotal);
    input.read(message.get_buffer(), messageTotal);
    message.add_size(messageTotal);

    // signature
    tmp[0] = input[AUTO];
    tmp[1] = input[AUTO];
    ato16(tmp, length);

    signature_ = NEW_YS byte[length];
    input.read(signature_, length);

    // verify signature
    byte hash[FINISHED_SZ];
    MD5  md5;
    SHA  sha;

    const Connection& conn = ssl.getSecurity().get_connection();
    // md5
    md5.update(conn.client_random_, RAN_LEN);
    md5.update(conn.server_random_, RAN_LEN);
    md5.update(message.get_buffer(), message.get_size());
    md5.get_digest(hash);

    // sha
    sha.update(conn.client_random_, RAN_LEN);
    sha.update(conn.server_random_, RAN_LEN);
    sha.update(message.get_buffer(), message.get_size());
    sha.get_digest(&hash[MD5_LEN]);

    const CertManager& cert = ssl.getCrypto().get_certManager();
    
    if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) {
        RSA rsa(cert.get_peerKey(), cert.get_peerKeyLength());
        if (!rsa.verify(hash, sizeof(hash), signature_, length))
            ssl.SetError(verify_error);
    }
    else {
        byte decodedSig[DSS_SIG_SZ];
        length = TaoCrypt::DecodeDSA_Signature(decodedSig, signature_, length);
        
        DSS dss(cert.get_peerKey(), cert.get_peerKeyLength());
        if (!dss.verify(&hash[MD5_LEN], SHA_LEN, decodedSig, length))
            ssl.SetError(verify_error);
    }

    // save input
    ssl.useCrypto().SetDH(NEW_YS DiffieHellman(parms_.get_p(),
               parms_.get_pSize(), parms_.get_g(), parms_.get_gSize(),
               parms_.get_pub(), parms_.get_pubSize(),
               ssl.getCrypto().get_random()));
}


DH_Server::DH_Server()
    : signature_(0), length_(0), keyMessage_(0)
{}


DH_Server::~DH_Server()
{
    ysArrayDelete(keyMessage_);
    ysArrayDelete(signature_);
}


int DH_Server::get_length() const
{
    return length_;
}


opaque* DH_Server::get_serverKey() const
{
    return keyMessage_;
}


// set available suites
Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers, 
                       ProtocolVersion pv) : entity_(ce)
{
    pending_ = true;	// suite not set yet

    if (ciphers.setSuites_) {   // use user set list
        suites_size_ = ciphers.suiteSz_;
        memcpy(suites_, ciphers.suites_, ciphers.suiteSz_);
        SetCipherNames();
    }
    else 
        SetSuites(pv);  // defaults
}


void Parameters::SetSuites(ProtocolVersion pv)
{
    int i = 0;
    // available suites, best first
    // when adding more, make sure cipher_names is updated and
    //      MAX_CIPHERS is big enough

    if (isTLS(pv)) {
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA;

        suites_[i++] = 0x00;
        suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA;

        suites_[i++] = 0x00;
        suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160;

        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160;

        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160;
        suites_[i++] = 0x00;
        suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160;
    }

    suites_[i++] = 0x00;
    suites_[i++] = SSL_RSA_WITH_RC4_128_SHA;  
    suites_[i++] = 0x00;
    suites_[i++] = SSL_RSA_WITH_RC4_128_MD5;

    suites_[i++] = 0x00;
    suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
    suites_[i++] = 0x00;
    suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA;

    suites_[i++] = 0x00;
    suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA;  
    suites_[i++] = 0x00;
    suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; 

    suites_[i++] = 0x00;
    suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA;  
    suites_[i++] = 0x00;
    suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA;

    suites_size_ = i;

    SetCipherNames();
}


void Parameters::SetCipherNames()
{
    const int suites = suites_size_ / 2;
    int pos = 0;

    for (int j = 0; j < suites; j++) {
        int index = suites_[j*2 + 1];  // every other suite is suite id
        int len = strlen(cipher_names[index]) + 1;
        strncpy(cipher_list_[pos++], cipher_names[index], len);
    }
    cipher_list_[pos][0] = 0;
}

⌨️ 快捷键说明

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