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

📄 ssl2mesg.c

📁 Netscape公司提供的安全套接字层
💻 C
📖 第 1 页 / 共 2 页
字号:
    
    memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
    if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
        return err;
    
    if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize)
        return ERR(SSLProtocolErr);
    
/* Stash the IV after the master key in master secret storage */
    memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
    progress += keyArgLength;
    ASSERT(progress = msg.data + msg.length);
    
    return SSLNoErr;
}

SSLErr
SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
{   SSLErr              err;
    int                 length, i, clearLen, rsaResult;
    unsigned int        outputLen, peerKeyModulusLen;
    SSLBuffer           keyData;
    uint8               *progress;
    SSLRandomCtx        rsaRandom;

#if RSAREF
    peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
#elif BSAFE
    {   A_RSA_KEY   *keyInfo;
        int         rsaResult;
        
        if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
            return SSLUnknownErr;
        peerKeyModulusLen = keyInfo->modulus.len;
    }
#endif /* RSAREF / BSAFE */

/* Length is 10 + clear key size + encrypted output size + iv size */
    length = 10;
    clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
    length += clearLen;
    length += peerKeyModulusLen;
    length += ctx->selectedCipherSpec->cipher->ivSize;
    
    if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
        return err;
    progress = msg->data;
    *progress++ = ssl2_mt_client_master_key;
    for (i = 0; i < SSL2CipherMapCount; i++)
        if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
            break;
    ASSERT(i < SSL2CipherMapCount);
    progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
    progress = SSLEncodeInt(progress, clearLen, 2);
    progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
    progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
    
    /* Generate the keying material; we need enough data for the key and IV */
    keyData.data = ctx->masterSecret;
    keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
    ASSERT(keyData.length <= 48);   /* Must be able to store it in the masterSecret array */
    if (ERR(err = ctx->sysCtx.random(keyData, ctx->sysCtx.randomRef)) != 0)
        return err;
    
    memcpy(progress, ctx->masterSecret, clearLen);
    progress += clearLen;
    
    if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
        return err;
    
/* Replace this with code to do encryption at lower level & set PKCS1 padding
    for rollback attack */
#if RSAREF
    if ((rsaResult = RSAPublicEncrypt(progress, &outputLen,
                                ctx->masterSecret + clearLen,
                                ctx->selectedCipherSpec->cipher->keySize - clearLen,
                                &ctx->peerKey,&rsaRandom)) != 0)
    {   R_RandomFinal(&rsaRandom);
        return ERR(SSLUnknownErr);
    }
#elif BSAFE
    {   B_ALGORITHM_OBJ     rsa;
        B_ALGORITHM_METHOD  *chooser[] = { &AM_RSA_ENCRYPT, 0 };
        unsigned int        encryptedOut;
        
        if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
            return SSLUnknownErr;
        if ((rsaResult = B_EncryptUpdate(rsa, progress,
                    &encryptedOut, peerKeyModulusLen, ctx->masterSecret + clearLen,
                    ctx->selectedCipherSpec->cipher->keySize - clearLen,
                    rsaRandom, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen = encryptedOut;
        if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
                    &encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
            return SSLUnknownErr;
        outputLen += encryptedOut;
        B_DestroyAlgorithmObject(&rsa);
    }
#endif

    progress += outputLen;
    
#if RSAREF
    R_RandomFinal(&rsaRandom);
#elif BSAFE
    B_DestroyAlgorithmObject(&rsaRandom);
#endif
        
    memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
            ctx->selectedCipherSpec->cipher->ivSize);
    progress += ctx->selectedCipherSpec->cipher->ivSize;
    
    ASSERT(progress == msg->data + msg->length);
    
    return SSLNoErr;
}

SSLErr
SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
{   if (msg.length != ctx->sessionID.length)
        return ERR(SSLProtocolErr);
    
    if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0)
        return ERR(SSLProtocolErr);
    
    return SSLNoErr;
}

SSLErr
SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
{   SSLErr      err;
    
    if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
        return err;
    msg->data[0] = ssl2_mt_client_finished;
    memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
    return SSLNoErr;
}

SSLErr
SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
{   SSLErr              err;
    SSL2CertTypeCode    certType;
    int                 sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
    int                 i, j;
    SSL2CipherKind      cipherKind;
    SSLBuffer           certBuf;
    SSLCertificate      *cert;
    CipherSuite         matchingCipher, selectedCipher;
    uint8               *progress;
    SSLProtocolVersion  version;
    
    if (msg.length < 10)
        return ERR(SSLProtocolErr);
    
    progress = msg.data;
    
    sessionIDMatch = *progress++;
    certType = (SSL2CertTypeCode)*progress++;
    version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
    progress += 2;
    if (version != SSL_Version_2_0)
        return ERR(SSLProtocolErr);
    ctx->protocolVersion = version;
    certLen = SSLDecodeInt(progress, 2);
    progress += 2;
    cipherSpecsLen = SSLDecodeInt(progress, 2);
    progress += 2;
    connectionIDLen = SSLDecodeInt(progress, 2);
    progress += 2;
    
    if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
        (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
        return ERR(SSLProtocolErr);
    if (sessionIDMatch != 0)
    {   if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
            return ERR(SSLProtocolErr);
        ctx->ssl2SessionMatch = 1;
        
        ctx->ssl2ConnectionIDLength = connectionIDLen;
        memcpy(ctx->serverRandom, progress, connectionIDLen);
        progress += connectionIDLen;
    }
    else
    {   if (certType != ssl2_ct_x509_certificate)
            return ERR(SSLNegotiationErr);
        cipherSpecsLen /= 3;
        
        if (ERR(err = SSLAllocBuffer(&certBuf, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
            return err;
        cert = (SSLCertificate*)certBuf.data;
        cert->next = 0;
        if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
        {   ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
            return err;
        }
        memcpy(cert->derCert.data, progress, certLen);
        progress += certLen;
        if (ERR(err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
        {   ERR(SSLFreeBuffer(&cert->derCert, &ctx->sysCtx));
            ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
            return err;
        }
        ctx->peerCert = cert;
        if (ERR(err = X509ExtractPublicKey(&cert->cert.pubKey, &ctx->peerKey)) != 0)
            return err;
        
        selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
        for (i = 0; i < cipherSpecsLen; i++)
        {   cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
            progress += 3;
            if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)  /* After we find one, just keep advancing progress past the unused ones */
            {   for (j = 0; j < SSL2CipherMapCount; j++)
                    if (cipherKind == SSL2CipherMap[j].cipherKind)
                    {   matchingCipher = SSL2CipherMap[j].cipherSuite;
                        break;
                    }
                for (j = 0; j < CipherSpecCount; j++)   
                    if (KnownCipherSpecs[j].cipherSpec == matchingCipher)
                    {   selectedCipher = matchingCipher;
                        break;
                    }
            }
        }
        if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
            return ERR(SSLNegotiationErr);
        
        ctx->selectedCipher = selectedCipher;
        if (ERR(err = FindCipherSpec(ctx->selectedCipher, &ctx->selectedCipherSpec)) != 0)
            return err;
        ctx->ssl2ConnectionIDLength = connectionIDLen;
        memcpy(ctx->serverRandom, progress, connectionIDLen);
        progress += connectionIDLen;
    }
    
    ASSERT(progress == msg.data + msg.length);
    
    return SSLNoErr;
}

SSLErr
SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
{   SSLErr              err;
    SSLCertificate      *cert;
    SSLBuffer           randomData;
    uint8               *progress;
    int                 i;
    
    /* Create the connection ID */
    ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
    randomData.data = ctx->serverRandom;
    randomData.length = ctx->ssl2ConnectionIDLength;
    if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
        return err;
        
    if (ctx->ssl2SessionMatch != 0)
    {   if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
            return err;
        progress = msg->data;
        *progress++ = ssl2_mt_server_hello;
        *progress++ = ctx->ssl2SessionMatch;
        *progress++ = 0;    /* cert type */
        progress = SSLEncodeInt(progress, ctx->protocolVersion, 2);
        progress = SSLEncodeInt(progress, 0, 2);    /* cert len */
        progress = SSLEncodeInt(progress, 0, 2);    /* cipherspecs len */
        progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
        memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
        progress += ctx->ssl2ConnectionIDLength;
    }
    else
    {   /* First, find the last cert in the chain; it's the one we'll send */
        ASSERT(ctx->localCert != 0);
        cert = ctx->localCert;
        while (cert->next != 0)
            cert = cert->next;
        
        if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
            return err;
        progress = msg->data;
        *progress++ = ssl2_mt_server_hello;
        *progress++ = ctx->ssl2SessionMatch;
        *progress++ = ssl2_ct_x509_certificate; /* cert type */
        progress = SSLEncodeInt(progress, ctx->protocolVersion, 2);
        progress = SSLEncodeInt(progress, cert->derCert.length, 2);
        progress = SSLEncodeInt(progress, 3, 2);    /* cipherspecs len */
        progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
        memcpy(progress, cert->derCert.data, cert->derCert.length);
        progress += cert->derCert.length;
        for (i = 0; i < SSL2CipherMapCount; i++)
            if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
                break;
        ASSERT(i < SSL2CipherMapCount);
        progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
        memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
        progress += ctx->ssl2ConnectionIDLength;
    }
    
    ASSERT(progress == msg->data + msg->length);
    return SSLNoErr;
}

SSLErr
SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
{   if (msg.length != ctx->ssl2ChallengeLength)
        return ERR(SSLProtocolErr);
    
    if (memcmp(msg.data, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
                    ctx->ssl2ChallengeLength) != 0)
        return ERR(SSLProtocolErr);
    
    return SSLNoErr;
}

SSLErr
SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
{   SSLErr      err;
    
    if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
        return err;
    
    msg->data[0] = ssl2_mt_server_verify;
    memcpy(msg->data+1, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
                    ctx->ssl2ChallengeLength);
    
    return SSLNoErr;
}

SSLErr
SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
{   SSLErr      err;
    
    if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
        return err;
    memcpy(ctx->sessionID.data, msg.data, msg.length);
    return SSLNoErr;
}

SSLErr
SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
{   SSLErr      err;
    
    if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
        return err;
    
    msg->data[0] = ssl2_mt_server_finished;
    memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
    
    return SSLNoErr;
}

⌨️ 快捷键说明

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