Esempio n. 1
0
SECStatus 
SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
{
    sslSocket *      ss;
    SSLChannelInfo   inf;
    sslSessionID *   sid;

    if (!info || len < sizeof inf.length) { 
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

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

    memset(&inf, 0, sizeof inf);
    inf.length = PR_MIN(sizeof inf, len);

    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
        sid = ss->sec.ci.sid;
	inf.protocolVersion  = ss->version;
	inf.authKeyBits      = ss->sec.authKeyBits;
	inf.keaKeyBits       = ss->sec.keaKeyBits;
	if (ss->version < SSL_LIBRARY_VERSION_3_0) { 
	    inf.cipherSuite           = ss->sec.cipherType | 0xff00;
	    inf.compressionMethod     = ssl_compression_null;
	    inf.compressionMethodName = "N/A";
	} else if (ss->ssl3.initialized) { 	
	    ssl_GetSpecReadLock(ss);
	    inf.cipherSuite           = ss->ssl3.hs.cipher_suite;
	    inf.compressionMethod     = ss->ssl3.cwSpec->compression_method;
	    ssl_ReleaseSpecReadLock(ss);
	    inf.compressionMethodName =
		ssl_GetCompressionMethodName(inf.compressionMethod);
	}
	if (sid) {
	    inf.creationTime   = sid->creationTime;
	    inf.lastAccessTime = sid->lastAccessTime;
	    inf.expirationTime = sid->expirationTime;
	    if (ss->version < SSL_LIBRARY_VERSION_3_0) { 
	        inf.sessionIDLength = SSL2_SESSIONID_BYTES;
		memcpy(inf.sessionID, sid->u.ssl2.sessionID, 
		       SSL2_SESSIONID_BYTES);
	    } else {
		unsigned int sidLen = sid->u.ssl3.sessionIDLength;
	        sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
	        inf.sessionIDLength = sidLen;
		memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
	    }
	}
    }

    memcpy(info, &inf, inf.length);

    return SECSuccess;
}
Esempio n. 2
0
SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra) {
  sslSocket *ss;
  sslSequenceNumber to;

  ss = ssl_FindSocket(fd);
  if (!ss) {
    return SECFailure;
  }
  ssl_GetSpecReadLock(ss);
  to = ss->ssl3.cwSpec->write_seq_num + DTLS_RECVD_RECORDS_WINDOW + extra;
  ssl_ReleaseSpecReadLock(ss);
  return SSLInt_AdvanceWriteSeqNum(fd, to & RECORD_SEQ_MAX);
}
Esempio n. 3
0
SECItem *
SSL_GetNegotiatedHostInfo(PRFileDesc *fd)
{
    SECItem *sniName = NULL;
    sslSocket *ss;
    char *name = NULL;

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

    if (ss->sec.isServer) {
        if (ss->version > SSL_LIBRARY_VERSION_3_0 &&
            ss->ssl3.initialized) { /* TLS */
            SECItem *crsName;
            ssl_GetSpecReadLock(ss); /*********************************/
            crsName = &ss->ssl3.hs.srvVirtName;
            if (crsName->data) {
                sniName = SECITEM_DupItem(crsName);
            }
            ssl_ReleaseSpecReadLock(ss); /*----------------------------*/
        }
        return sniName;
    }
    name = SSL_RevealURL(fd);
    if (name) {
        sniName = PORT_ZNew(SECItem);
        if (!sniName) {
            PORT_Free(name);
            return NULL;
        }
        sniName->data = (void *)name;
        sniName->len = PORT_Strlen(name);
    }
    return sniName;
}
Esempio n. 4
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;
}
Esempio n. 5
0
SECStatus
SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
{
    sslSocket *ss;
    SSLChannelInfo inf;
    sslSessionID *sid;

    /* Check if we can properly return the length of data written and that
     * we're not asked to return more information than we know how to provide.
     */
    if (!info || len < sizeof inf.length || len > sizeof inf) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

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

    memset(&inf, 0, sizeof inf);
    inf.length = PR_MIN(sizeof inf, len);

    if (ss->opt.useSecurity && ss->enoughFirstHsDone) {
        sid = ss->sec.ci.sid;
        inf.protocolVersion = ss->version;
        inf.authKeyBits = ss->sec.authKeyBits;
        inf.keaKeyBits = ss->sec.keaKeyBits;
        if (ss->ssl3.initialized) {
            SSLCipherSuiteInfo cinfo;
            SECStatus rv;

            ssl_GetSpecReadLock(ss);
            /* XXX  The cipher suite should be in the specs and this
             * function should get it from cwSpec rather than from the "hs".
             * See bug 275744 comment 69 and bug 766137.
             */
            inf.cipherSuite = ss->ssl3.hs.cipher_suite;
            inf.compressionMethod = ss->ssl3.cwSpec->compression_method;
            ssl_ReleaseSpecReadLock(ss);
            inf.compressionMethodName =
                ssl_GetCompressionMethodName(inf.compressionMethod);

            /* Fill in the cipher details from the cipher suite. */
            rv = SSL_GetCipherSuiteInfo(inf.cipherSuite,
                                        &cinfo, sizeof(cinfo));
            if (rv != SECSuccess) {
                return SECFailure; /* Error code already set. */
            }
            inf.symCipher = cinfo.symCipher;
            inf.macAlgorithm = cinfo.macAlgorithm;
            /* Get these fromm |ss->sec| because that is accurate
             * even with TLS 1.3 disaggregated cipher suites. */
            inf.keaType = ss->sec.keaType;
            inf.keaGroup = ss->sec.keaGroup ? ss->sec.keaGroup->name : ssl_grp_none;
            inf.keaKeyBits = ss->sec.keaKeyBits;
            inf.authType = ss->sec.authType;
            inf.authKeyBits = ss->sec.authKeyBits;
            inf.signatureScheme = ss->sec.signatureScheme;
        }
        if (sid) {
            unsigned int sidLen;

            inf.creationTime = sid->creationTime;
            inf.lastAccessTime = sid->lastAccessTime;
            inf.expirationTime = sid->expirationTime;
            inf.extendedMasterSecretUsed =
                (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ||
                 sid->u.ssl3.keys.extendedMasterSecretUsed)
                    ? PR_TRUE
                    : PR_FALSE;

            inf.earlyDataAccepted =
                (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted ||
                 ss->ssl3.hs.zeroRttState == ssl_0rtt_done);
            sidLen = sid->u.ssl3.sessionIDLength;
            sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
            inf.sessionIDLength = sidLen;
            memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
        }
    }

    memcpy(info, &inf, inf.length);

    return SECSuccess;
}
Esempio n. 6
0
SECStatus 
SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len)
{
    sslSocket *      ss;
    SSLChannelInfo   inf;
    sslSessionID *   sid;
    PRBool           enoughFirstHsDone = PR_FALSE;

    if (!info || len < sizeof inf.length) { 
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

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

    memset(&inf, 0, sizeof inf);
    inf.length = PR_MIN(sizeof inf, len);

    if (ss->firstHsDone) {
	enoughFirstHsDone = PR_TRUE;
    } else if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
	       ssl3_CanFalseStart(ss)) {
	enoughFirstHsDone = PR_TRUE;
    }

    if (ss->opt.useSecurity && enoughFirstHsDone) {
        sid = ss->sec.ci.sid;
	inf.protocolVersion  = ss->version;
	inf.authKeyBits      = ss->sec.authKeyBits;
	inf.keaKeyBits       = ss->sec.keaKeyBits;
	if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
	    inf.cipherSuite           = ss->sec.cipherType | 0xff00;
	    inf.compressionMethod     = ssl_compression_null;
	    inf.compressionMethodName = "N/A";
	} else if (ss->ssl3.initialized) { 	/* SSL3 and TLS */
	    ssl_GetSpecReadLock(ss);
	    /* XXX  The cipher suite should be in the specs and this
	     * function should get it from crSpec rather than from the "hs".
	     * See bug 275744 comment 69.
	     */
	    inf.cipherSuite           = ss->ssl3.hs.cipher_suite;
	    inf.compressionMethod     = ss->ssl3.crSpec->compression_method;
	    ssl_ReleaseSpecReadLock(ss);
	    inf.compressionMethodName =
		ssl_GetCompressionMethodName(inf.compressionMethod);
	}
	if (sid) {
	    inf.creationTime   = sid->creationTime;
	    inf.lastAccessTime = sid->lastAccessTime;
	    inf.expirationTime = sid->expirationTime;
	    if (ss->version < SSL_LIBRARY_VERSION_3_0) { /* SSL2 */
	        inf.sessionIDLength = SSL2_SESSIONID_BYTES;
		memcpy(inf.sessionID, sid->u.ssl2.sessionID, 
		       SSL2_SESSIONID_BYTES);
	    } else {
		unsigned int sidLen = sid->u.ssl3.sessionIDLength;
	        sidLen = PR_MIN(sidLen, sizeof inf.sessionID);
	        inf.sessionIDLength = sidLen;
		memcpy(inf.sessionID, sid->u.ssl3.sessionID, sidLen);
	    }
	}
    }

    memcpy(info, &inf, inf.length);

    return SECSuccess;
}
Esempio n. 7
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;
}