Exemplo n.º 1
0
SECStatus
SSL_ExportKeyingMaterial(PRFileDesc *fd,
                         const char *label, unsigned int labelLen,
                         PRBool hasContext,
                         const unsigned char *context, unsigned int contextLen,
                         unsigned char *out, unsigned int outLen)
{
    sslSocket *ss;
    unsigned char *val = NULL;
    unsigned int valLen, i;
    SECStatus rv = SECFailure;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    if (!label || !labelLen || !out || !outLen ||
        (hasContext && (!context || !contextLen))) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
        return tls13_Exporter(ss, ss->ssl3.hs.exporterSecret,
                              label, labelLen,
                              context, hasContext ? contextLen : 0,
                              out, outLen);
    }

    if (hasContext && contextLen > MAX_CONTEXT_LEN) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* construct PRF arguments */
    valLen = SSL3_RANDOM_LENGTH * 2;
    if (hasContext) {
        valLen += 2 /* PRUint16 length */ + contextLen;
    }
    val = PORT_Alloc(valLen);
    if (!val) {
        return SECFailure;
    }
    i = 0;
    PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
    i += SSL3_RANDOM_LENGTH;
    PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
    i += SSL3_RANDOM_LENGTH;
    if (hasContext) {
        val[i++] = contextLen >> 8;
        val[i++] = contextLen;
        PORT_Memcpy(val + i, context, contextLen);
        i += contextLen;
    }
    PORT_Assert(i == valLen);

    /* Allow TLS keying material to be exported sooner, when the master
     * secret is available and we have sent ChangeCipherSpec.
     */
    ssl_GetSpecReadLock(ss);
    if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
        PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
        rv = SECFailure;
    } else {
        rv = ssl3_TLSPRFWithMasterSecret(ss, ss->ssl3.cwSpec, label, labelLen,
                                         val, valLen, out, outLen);
    }
    ssl_ReleaseSpecReadLock(ss);

    PORT_ZFree(val, valLen);
    return rv;
}
Exemplo n.º 2
0
SECStatus
SSL_ExportKeyingMaterial(PRFileDesc *fd,
                         const char *label, unsigned int labelLen,
                         PRBool hasContext,
                         const unsigned char *context, unsigned int contextLen,
                         unsigned char *out, unsigned int outLen)
{
    sslSocket *ss;
    unsigned char *val = NULL;
    unsigned int valLen, i;
    SECStatus rv = SECFailure;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in ExportKeyingMaterial",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    ssl_GetRecvBufLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    if (ss->version < SSL_LIBRARY_VERSION_3_1_TLS) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
	ssl_ReleaseSSL3HandshakeLock(ss);
	ssl_ReleaseRecvBufLock(ss);
	return SECFailure;
    }

    
    valLen = SSL3_RANDOM_LENGTH * 2;
    if (hasContext) {
	valLen += 2  + contextLen;
    }
    val = PORT_Alloc(valLen);
    if (!val) {
	ssl_ReleaseSSL3HandshakeLock(ss);
	ssl_ReleaseRecvBufLock(ss);
	return SECFailure;
    }
    i = 0;

    PORT_Memcpy(val + i, &ss->ssl3.hs.client_random.rand, SSL3_RANDOM_LENGTH);
    i += SSL3_RANDOM_LENGTH;
    PORT_Memcpy(val + i, &ss->ssl3.hs.server_random.rand, SSL3_RANDOM_LENGTH);
    i += SSL3_RANDOM_LENGTH;

    if (hasContext) {
	val[i++] = contextLen >> 8;
	val[i++] = contextLen;
	PORT_Memcpy(val + i, context, contextLen);
	i += contextLen;
    }
    PORT_Assert(i == valLen);

    ssl_GetSpecReadLock(ss);
    if (!ss->ssl3.cwSpec->master_secret && !ss->ssl3.cwSpec->msItem.len) {
	PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
	rv = SECFailure;
    } else {
	rv = ssl3_TLSPRFWithMasterSecret(ss->ssl3.cwSpec, label, labelLen, val,
					 valLen, out, outLen);
    }
    ssl_ReleaseSpecReadLock(ss);
    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_ReleaseRecvBufLock(ss);

    PORT_ZFree(val, valLen);
    return rv;
}