hdskkeys.c

来自「Netscape公司提供的安全套接字层」· C语言 代码 · 共 484 行 · 第 1/2 页

C
484
字号
    memcpy(serverPending->macSecret, keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
    DUMP_DATA_NAME("server write mac secret", keyDataProgress, ctx->selectedCipherSpec->macAlgorithm->digestSize);
    keyDataProgress += ctx->selectedCipherSpec->macAlgorithm->digestSize;
    
    if (ctx->selectedCipherSpec->isExportable == NotExportable)
    {   keyPtr = keyDataProgress;
        keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
        /* Skip server write key to get to IV */
        ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->secretKeySize;
        if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
                                    &clientPending->symCipherState, ctx)) != 0)
            goto fail;
        DUMP_DATA_NAME("client write key", keyPtr, ctx->selectedCipherSpec->cipher->secretKeySize);
        DUMP_DATA_NAME("client write iv", ivPtr, ctx->selectedCipherSpec->cipher->ivSize);
        keyPtr = keyDataProgress;
        keyDataProgress += ctx->selectedCipherSpec->cipher->secretKeySize;
        /* Skip client write IV to get to server write IV */
        ivPtr = keyDataProgress + ctx->selectedCipherSpec->cipher->ivSize;
        if ((err = ctx->selectedCipherSpec->cipher->initialize(keyPtr, ivPtr,
                                    &serverPending->symCipherState, ctx)) != 0)
            goto fail;
        DUMP_DATA_NAME("server write key", keyPtr, ctx->selectedCipherSpec->cipher->secretKeySize);
        DUMP_DATA_NAME("server write iv", ivPtr, ctx->selectedCipherSpec->cipher->ivSize);
    }
    else
    {   uint8           exportKey[16], exportIV[16];
        SSLBuffer       hashOutput, clientWrite, serverWrite, clientRandom,
                        serverRandom;
        
        ASSERT(ctx->selectedCipherSpec->cipher->keySize <= 16);
        ASSERT(ctx->selectedCipherSpec->cipher->ivSize <= 16);
        
        clientWrite.data = keyDataProgress;
        clientWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
        serverWrite.data = keyDataProgress + clientWrite.length;
        serverWrite.length = ctx->selectedCipherSpec->cipher->secretKeySize;
        clientRandom.data = ctx->clientRandom;
        clientRandom.length = 32;
        serverRandom.data = ctx->serverRandom;
        serverRandom.length = 32;
        
        if ((err = SSLAllocBuffer(&hashCtx, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
            goto fail;
        if ((err = SSLHashMD5.init(hashCtx)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, clientWrite)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
            goto fail;
        hashOutput.data = exportKey;
        hashOutput.length = 16;
        if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
            goto fail;
        
        if (ctx->selectedCipherSpec->cipher->ivSize > 0)
        {   if ((err = SSLHashMD5.init(hashCtx)) != 0)
                goto fail;
            if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
                goto fail;
            if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
                goto fail;
            hashOutput.data = exportIV;
            hashOutput.length = 16;
            if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
                goto fail;
        }
        if ((err = ctx->selectedCipherSpec->cipher->initialize(exportKey, exportIV,
                                    &clientPending->symCipherState, ctx)) != 0)
            goto fail;
        
        if ((err = SSLHashMD5.init(hashCtx)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, serverWrite)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
            goto fail;
        hashOutput.data = exportKey;
        hashOutput.length = 16;
        if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
            goto fail;
        
        if (ctx->selectedCipherSpec->cipher->ivSize > 0)
        {   if ((err = SSLHashMD5.init(hashCtx)) != 0)
                goto fail;
            if ((err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
                goto fail;
            if ((err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
                goto fail;
            hashOutput.data = exportIV;
            hashOutput.length = 16;
            if ((err = SSLHashMD5.final(hashCtx, hashOutput)) != 0)
                goto fail;
        }
        if ((err = ctx->selectedCipherSpec->cipher->initialize(exportKey, exportIV,
                                    &serverPending->symCipherState, ctx)) != 0)
            goto fail;
    }
    
/* Ciphers are ready for use */
    ctx->writePending.ready = 1;
    ctx->readPending.ready = 1;
    
/* Ciphers get swapped by sending or receiving a change cipher spec message */
    
    err = SSLNoErr;
fail:
    SSLFreeBuffer(&key, &ctx->sysCtx);
    SSLFreeBuffer(&hashCtx, &ctx->sysCtx);
    return err;
}

static SSLErr
SSLGenerateKeyMaterial(SSLBuffer key, SSLContext *ctx)
{   SSLErr      err;
    uint8       leaderData[10];     /* Max of 10 hashes (* 16 bytes/hash = 160 bytes of key) */
    uint8       shaHashData[20], md5HashData[16];
    SSLBuffer   shaContext, md5Context;
    uint8       *keyProgress;
    int         i,j,remaining, satisfied;
    SSLBuffer   leader, masterSecret, serverRandom, clientRandom, shaHash, md5Hash;
    
    ASSERT(key.length <= 16 * sizeof(leaderData));
    
    leader.data = leaderData;
    masterSecret.data = ctx->masterSecret;
    masterSecret.length = 48;
    serverRandom.data = ctx->serverRandom;
    serverRandom.length = 32;
    clientRandom.data = ctx->clientRandom;
    clientRandom.length = 32;
    shaHash.data = shaHashData;
    shaHash.length = 20;
    md5Hash.data = md5HashData;
    md5Hash.length = 20;
    
    md5Context.data = 0;
    shaContext.data = 0;
    if ((err = ReadyHash(&SSLHashMD5, &md5Context, ctx)) != 0)
        goto fail;
    if ((err = ReadyHash(&SSLHashSHA1, &shaContext, ctx)) != 0)
        goto fail;  
    
    keyProgress = key.data;
    remaining = key.length;
    
    for (i = 0; remaining > 0; ++i)
    {   for (j = 0; j <= i; j++)
            leaderData[j] = 0x41 + i;   /* 'A', 'BB', 'CCC', etc. */
        leader.length = i+1;
        
        if ((err = SSLHashSHA1.update(shaContext, leader)) != 0)
            goto fail;
        if ((err = SSLHashSHA1.update(shaContext, masterSecret)) != 0)
            goto fail;
        if ((err = SSLHashSHA1.update(shaContext, serverRandom)) != 0)
            goto fail;
        if ((err = SSLHashSHA1.update(shaContext, clientRandom)) != 0)
            goto fail;
        if ((err = SSLHashSHA1.final(shaContext, shaHash)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(md5Context, masterSecret)) != 0)
            goto fail;
        if ((err = SSLHashMD5.update(md5Context, shaHash)) != 0)
            goto fail;
        if ((err = SSLHashMD5.final(md5Context, md5Hash)) != 0)
            goto fail;
        
        satisfied = 16;
        if (remaining < 16)
            satisfied = remaining;
        memcpy(keyProgress, md5HashData, satisfied);
        remaining -= satisfied;
        keyProgress += satisfied;
        
        if ((err = SSLHashMD5.init(md5Context)) != 0)
            goto fail;
        if ((err = SSLHashSHA1.init(shaContext)) != 0)
            goto fail;
    }
    
    ASSERT(remaining == 0 && keyProgress == (key.data + key.length));
    err = SSLNoErr;
fail:
    SSLFreeBuffer(&md5Context, &ctx->sysCtx);
    SSLFreeBuffer(&shaContext, &ctx->sysCtx);
    
    return err;
}

SSLErr
ReadyRandom(SSLRandomCtx *rsaRandom, SSLContext *ctx)
{   SSLErr              err;
    SSLBuffer           randomSeedBuf;
    uint8               randomSeed[32];
    int                 rsaResult;
#if RSAREF
    unsigned int        bytesNeeded;
    
    if (R_RandomInit(rsaRandom) != 0)
        return ERR(SSLUnknownErr);
    if (R_GetRandomBytesNeeded(&bytesNeeded, rsaRandom) != 0)
        return ERR(SSLUnknownErr);
    
    randomSeedBuf.data = randomSeed;
    randomSeedBuf.length = 32;
    
    while (bytesNeeded > 0)
    {   if (ERR(err = ctx->sysCtx.random(randomSeedBuf, ctx->sysCtx.randomRef)) != 0)
            return err;
        if ((rsaResult = R_RandomUpdate(rsaRandom, randomSeed, 32)) != 0)
            return ERR(SSLUnknownErr);
        
        if (bytesNeeded >= 32)
            bytesNeeded -= 32;
        else
            bytesNeeded = 0;
    }
#elif BSAFE
    static B_ALGORITHM_OBJ  random;
    B_ALGORITHM_METHOD      *chooser[] = { &AM_MD5_RANDOM, 0 };
    
    if ((rsaResult = B_CreateAlgorithmObject(rsaRandom)) != 0)
        return ERR(SSLUnknownErr);
    if ((rsaResult = B_SetAlgorithmInfo(*rsaRandom, AI_MD5Random, 0)) != 0)
        return ERR(SSLUnknownErr);
    if ((rsaResult = B_RandomInit(*rsaRandom, chooser, NO_SURR)) != 0)
        return ERR(SSLUnknownErr);
    randomSeedBuf.data = randomSeed;
    randomSeedBuf.length = 32;
    if (ERR(err = ctx->sysCtx.random(randomSeedBuf, ctx->sysCtx.randomRef)) != 0)
        return err;
    if ((rsaResult = B_RandomUpdate(*rsaRandom, randomSeedBuf.data, randomSeedBuf.length, NO_SURR)) != 0)
        return ERR(SSLUnknownErr);
#endif /* RSAREF / BSAFE */
        
    return SSLNoErr;
}

⌨️ 快捷键说明

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