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

📄 hdskkyex.c

📁 Netscape公司提供的安全套接字层
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
            return err;
        
        progress = keyExch->contents.data;
        *progress++ = SSL_server_key_exchange;
        progress = SSLEncodeInt(progress, length, 3);
        
        progress = SSLEncodeInt(progress, params->prime.len, 2);
        memcpy(progress, params->prime.data, params->prime.len);
        progress += params->prime.len;
        
        progress = SSLEncodeInt(progress, params->base.len, 2);
        memcpy(progress, params->base.data, params->base.len);
        progress += params->base.len;
        
        progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
        memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
        progress += ctx->dhExchangePublic.length;
    }
#endif /* RSAREF / BSAFE */
        
    ASSERT(progress == keyExch->contents.data + keyExch->contents.length);
    
    return SSLNoErr;
}

SSLErr
SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
{   SSLErr      err;
    
    switch (ctx->selectedCipherSpec->keyExchangeMethod)
    {   case SSL_RSA:
        case SSL_RSA_EXPORT:
            if (ERR(err = SSLProcessRSAServerKeyExchange(message, ctx)) != 0)
                return err;
            break;
        case SSL_DH_anon:
            if (ERR(err = SSLProcessDHanonServerKeyExchange(message, ctx)) != 0)
                return err;
            break;
        default:
            return ERR(SSLUnsupportedErr);
    }
    
    return SSLNoErr;
}

static SSLErr
SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx)
{   SSLErr          err;
    SSLBuffer       tempPubKey, hashOut, hashCtx, clientRandom, serverRandom;
    uint16          modulusLen, exponentLen, signatureLen;
    uint8           *progress, *modulus, *exponent, *signature;
    uint8           hash[20];
    unsigned int    outputLen;
    SSLBuffer       signedHashes;
    
    signedHashes.data = 0;
    hashCtx.data = 0;
    
    if (message.length < 2)
        return ERR(SSLProtocolErr);
    progress = message.data;
    modulusLen = SSLDecodeInt(progress, 2);
    modulus = progress + 2;
    progress += 2+modulusLen;
    if (message.length < 4 + modulusLen)
        return ERR(SSLProtocolErr);
    exponentLen = SSLDecodeInt(progress, 2);
    exponent = progress + 2;
    progress += 2+exponentLen;
    if (message.length < 6 + modulusLen + exponentLen)
        return ERR(SSLProtocolErr);
    signatureLen = SSLDecodeInt(progress, 2);
    signature = progress + 2;
    if (message.length != 6 + modulusLen + exponentLen + signatureLen)
        return ERR(SSLProtocolErr);
    
#if RSAREF
    {   /* Allocate room for the signed hashes; RSA can encrypt data
            as long as the modulus */
        if (ERR(err = SSLAllocBuffer(&signedHashes, (ctx->peerKey.bits + 7)/8, &ctx->sysCtx)) != 0)
            return err;

        if ((RSAPublicDecrypt(signedHashes.data, &outputLen, signature, signatureLen,
                            &ctx->peerKey)) != 0)
        {   ERR(err = SSLUnknownErr);
            goto fail;
        }
    }
#elif BSAFE
    {   B_ALGORITHM_OBJ     rsa;
        B_ALGORITHM_METHOD  *chooser[] = { &AM_MD2, &AM_MD5, &AM_RSA_DECRYPT, 0 };
        int                 rsaResult;
        unsigned int        decryptLen;
        
        /* Allocate room for the signed hashes; BSAFE makes sure we don't decode too much data */
        if (ERR(err = SSLAllocBuffer(&signedHashes, 36, &ctx->sysCtx)) != 0)
            return err; 
    
        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_DecryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_DecryptUpdate(rsa, signedHashes.data, &decryptLen, 36,
                    signature, signatureLen, 0, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen = decryptLen;
        if ((rsaResult = B_DecryptFinal(rsa, signedHashes.data+outputLen,
                    &decryptLen, 36-outputLen, 0, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen += decryptLen;
        B_DestroyAlgorithmObject(&rsa);
    }
#endif

    if (outputLen != 36)
    {   ERR(err = SSLProtocolErr);
        goto fail;
    }
    
    clientRandom.data = ctx->clientRandom;
    clientRandom.length = 32;
    serverRandom.data = ctx->serverRandom;
    serverRandom.length = 32;
    tempPubKey.data = message.data;
    tempPubKey.length = modulusLen + exponentLen + 4;
    hashOut.data = hash;
    
    hashOut.length = 16;
    if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.update(hashCtx, tempPubKey)) != 0)
        goto fail;
    if (ERR(err = SSLHashMD5.final(hashCtx, hashOut)) != 0)
        goto fail;
    if ((memcmp(hash, signedHashes.data, 16)) != 0)
    {   ERR(err = SSLProtocolErr);
        goto fail;
    }
    if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
        goto fail;
    
    hashOut.length = 20;
    if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.update(hashCtx, tempPubKey)) != 0)
        goto fail;
    if (ERR(err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)
        goto fail;
    if ((memcmp(hash, signedHashes.data + 16, 20)) != 0)
    {   ERR(err = SSLProtocolErr);
        goto fail;
    }
    
/* Signature matches; now replace server key with new key */
#if RSAREF
    memset(&ctx->peerKey, 0, sizeof(R_RSA_PUBLIC_KEY));
    memcpy(ctx->peerKey.modulus + (MAX_RSA_MODULUS_LEN - modulusLen),
            modulus, modulusLen);
    memcpy(ctx->peerKey.exponent + (MAX_RSA_MODULUS_LEN - exponentLen),
            exponent, exponentLen);
    
/* Adjust bit length for leading zeros in value; assume no more than 8 leading zero bits */
    {   unsigned int    bitAdjust;
        uint8           c;
        
        c = modulus[0];
        
        bitAdjust = 8;
        while (c != 0)
        {   --bitAdjust;
            c >>= 1;
        }
        ctx->peerKey.bits = modulusLen * 8 - bitAdjust;
    }
#elif BSAFE
    {   A_RSA_KEY   pubKeyInfo;
        int         rsaErr;
        
        pubKeyInfo.modulus.data = modulus;
        pubKeyInfo.modulus.len = modulusLen;
        pubKeyInfo.exponent.data = exponent;
        pubKeyInfo.exponent.len = exponentLen;
        
        if ((rsaErr = B_CreateKeyObject(&ctx->peerKey)) != 0)
            return SSLUnknownErr;
        if ((rsaErr = B_SetKeyInfo(ctx->peerKey, KI_RSAPublic, (POINTER)&pubKeyInfo)) != 0)
            return SSLUnknownErr;
    }
#endif /* RSAREF / BSAFE */
    err = SSLNoErr;
fail:
    ERR(SSLFreeBuffer(&signedHashes, &ctx->sysCtx));
    ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
    return err;
}

static SSLErr
SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
{   SSLErr          err;
    uint8           *progress;
    unsigned int    totalLength;
    
    if (message.length < 6)
        return ERR(SSLProtocolErr);
    
    progress = message.data;
    totalLength = 0;
    
#if RSAREF
    {   SSLBuffer       alloc;
        uint8           *prime, *generator, *publicVal;
        
        ctx->peerDHParams.primeLen = SSLDecodeInt(progress, 2);
        progress += 2;
        prime = progress;
        progress += ctx->peerDHParams.primeLen;
        totalLength += ctx->peerDHParams.primeLen;
        if (message.length < 6 + totalLength)
            return ERR(SSLProtocolErr);
        
        ctx->peerDHParams.generatorLen = SSLDecodeInt(progress, 2);
        progress += 2;
        generator = progress;
        progress += ctx->peerDHParams.generatorLen;
        totalLength += ctx->peerDHParams.generatorLen;
        if (message.length < 6 + totalLength)
            return ERR(SSLProtocolErr);
            
        ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
        progress += 2;
        publicVal = progress;
        progress += ctx->dhPeerPublic.length;
        totalLength += ctx->dhPeerPublic.length;
        if (message.length != 6 + totalLength)
            return ERR(SSLProtocolErr);
        
        ASSERT(progress == message.data + message.length);
        
        if (ERR(err = SSLAllocBuffer(&alloc, ctx->peerDHParams.primeLen +
                                    ctx->peerDHParams.generatorLen, &ctx->sysCtx)) != 0)
            return err;
        
        ctx->peerDHParams.prime = alloc.data;
        memcpy(ctx->peerDHParams.prime, prime, ctx->peerDHParams.primeLen);
        ctx->peerDHParams.generator = alloc.data + ctx->peerDHParams.primeLen;
        memcpy(ctx->peerDHParams.generator, generator, ctx->peerDHParams.generatorLen);
        
        if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic,
                                ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
            return err;
        
        memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
    }
#elif BSAFE
    {   int                     rsaErr;
        unsigned char           *publicVal;
        A_DH_KEY_AGREE_PARAMS   params;
        B_ALGORITHM_METHOD      *chooser[] = { &AM_DH_KEY_AGREE, 0 };

        params.prime.len = SSLDecodeInt(progress, 2);
        progress += 2;
        params.prime.data = progress;
        progress += params.prime.len;
        totalLength += params.prime.len;
        if (message.length < 6 + totalLength)
            return ERR(SSLProtocolErr);
        
        params.base.len = SSLDecodeInt(progress, 2);
        progress += 2;
        params.base.data = progress;
        progress += params.base.len;
        totalLength += params.base.len;
        if (message.length < 6 + totalLength)
            return ERR(SSLProtocolErr);
        
        ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
        if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic, ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
            return err;
        
        progress += 2;
        publicVal = progress;
        progress += ctx->dhPeerPublic.length;
        totalLength += ctx->dhPeerPublic.length;

⌨️ 快捷键说明

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