예제 #1
0
SECStatus
SSL_RestartHandshakeAfterChannelIDReq(PRFileDesc *      fd,
				      SECKEYPublicKey * channelIDPub,
				      SECKEYPrivateKey *channelID)
{
    sslSocket *   ss = ssl_FindSocket(fd);
    SECStatus     ret;

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in"
		 " SSL_RestartHandshakeAfterChannelIDReq",
		 SSL_GETPID(), fd));
	goto loser;
    }


    ssl_Get1stHandshakeLock(ss);

    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
	ssl_Release1stHandshakeLock(ss);
	goto loser;
    }

    ret = ssl3_RestartHandshakeAfterChannelIDReq(ss, channelIDPub,
						 channelID);
    ssl_Release1stHandshakeLock(ss);

    return ret;

loser:
    SECKEY_DestroyPublicKey(channelIDPub);
    SECKEY_DestroyPrivateKey(channelID);
    return SECFailure;
}
예제 #2
0
SECStatus
SSL_ExportEarlyKeyingMaterial(PRFileDesc *fd,
                              const char *label, unsigned int labelLen,
                              const unsigned char *context,
                              unsigned int contextLen,
                              unsigned char *out, unsigned int outLen)
{
    sslSocket *ss;

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

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

    return tls13_Exporter(ss, ss->ssl3.hs.earlyExporterSecret,
                          label, labelLen, context, contextLen,
                          out, outLen);
}
예제 #3
0
파일: sslinfo.c 프로젝트: ekr/nss-old
SECStatus
SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
                              SSLPreliminaryChannelInfo *info,
                              PRUintn len)
{
    sslSocket *ss;
    SSLPreliminaryChannelInfo inf;

    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_GetPreliminaryChannelInfo",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
        PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION);
        return SECFailure;
    }

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

    inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
    inf.protocolVersion = ss->version;
    inf.cipherSuite = ss->ssl3.hs.cipher_suite;

    memcpy(info, &inf, inf.length);
    return SECSuccess;
}
예제 #4
0
/* See documentation in ssl.h */
SECStatus
SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error)
{
    SECStatus rv;
    sslSocket *ss = ssl_FindSocket(fd);

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

    ssl_Get1stHandshakeLock(ss);

    if (!ss->ssl3.initialized) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    } else if (ss->version < SSL_LIBRARY_VERSION_3_0) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
	rv = SECFailure;
    } else {
	rv = ssl3_AuthCertificateComplete(ss, error);
    }

    ssl_Release1stHandshakeLock(ss);

    return rv;
}
예제 #5
0
SECStatus
SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
                              SSLPreliminaryChannelInfo *info,
                              PRUintn len)
{
    sslSocket *ss;
    SSLPreliminaryChannelInfo inf;

    /* 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_GetPreliminaryChannelInfo",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

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

    inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
    inf.protocolVersion = ss->version;
    inf.cipherSuite = ss->ssl3.hs.cipher_suite;

    memcpy(info, &inf, inf.length);
    return SECSuccess;
}
예제 #6
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;
}
예제 #7
0
/*
 * Allow the application to pass the url or hostname into the SSL library
 * so that we can do some checking on it. It will be used for the value in
 * SNI extension of client hello message.
 */
SECStatus
SSL_SetURL(PRFileDesc *fd, const char *url)
{
    sslSocket *   ss = ssl_FindSocket(fd);
    SECStatus     rv = SECSuccess;

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

    if ( ss->url ) {
	PORT_Free((void *)ss->url);	/* CONST */
    }

    ss->url = (const char *)PORT_Strdup(url);
    if ( ss->url == NULL ) {
	rv = SECFailure;
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return rv;
}
예제 #8
0
/* Register an application callback to be called when false start may happen.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb,
			     void *arg)
{
    sslSocket *ss;

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

    if (!ss->opt.useSecurity) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    ss->canFalseStartCallback     = cb;
    ss->canFalseStartCallbackData = arg;

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}
예제 #9
0
int 
ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa)
{
    PRFileDesc *osfd = ss->fd->lower;
    int rv;

    if ( ss->opt.handshakeAsServer ) {
	ss->securityHandshake = ssl2_BeginServerHandshake;
	ss->handshaking = sslHandshakingAsServer;
    } else {
	ss->securityHandshake = ssl2_BeginClientHandshake;
	ss->handshaking = sslHandshakingAsClient;
    }

    /* connect to server */
    rv = osfd->methods->connect(osfd, sa, ss->cTimeout);
    if (rv == PR_SUCCESS) {
	ss->TCPconnected = 1;
    } else {
	int err = PR_GetError();
	SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d",
		 SSL_GETPID(), ss->fd, err));
	if (err == PR_IS_CONNECTED_ERROR) {
	    ss->TCPconnected = 1;
	} 
    }

    SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d",
		SSL_GETPID(), ss->fd, rv));
    return rv;
}
예제 #10
0
SECStatus
SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart)
{
    sslSocket *ss;

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

    if (!ss->ssl3.initialized) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
	return SECFailure;
    }

    /* Require a forward-secret key exchange. */
    *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss ||
		     ss->ssl3.hs.kea_def->kea == kea_dhe_rsa ||
		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa ||
		     ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa;

    return SECSuccess;
}
예제 #11
0
파일: sslsecur.c 프로젝트: MekliCZ/positron
/* For SSLv2, does nothing but return an error.
** For SSLv3, flushes SID cache entry (if requested),
** and then starts new client hello or hello request.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
{
    sslSocket *ss;
    SECStatus rv;

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

    if (!ss->opt.useSecurity)
        return SECSuccess;

    ssl_Get1stHandshakeLock(ss);

    ssl_GetSSL3HandshakeLock(ss);
    rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
    ssl_ReleaseSSL3HandshakeLock(ss);

    ssl_Release1stHandshakeLock(ss);

    return rv;
}
예제 #12
0
파일: sslsecur.c 프로젝트: MekliCZ/positron
/*
 * Allow the application to pass the set of trust anchors
 */
SECStatus
SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList)
{
    sslSocket *ss = ssl_FindSocket(fd);
    CERTDistNames *names = NULL;

    if (!certList) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    names = CERT_DistNamesFromCertList(certList);
    if (names == NULL) {
        return SECFailure;
    }
    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);
    if (ss->ssl3.ca_list) {
        CERT_FreeDistNames(ss->ssl3.ca_list);
    }
    ss->ssl3.ca_list = names;
    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}
예제 #13
0
파일: sslauth.c 프로젝트: agamdua/libjingle
/* NEED LOCKS IN HERE.  */
SECStatus
SSL_PeerCertificateChain(PRFileDesc *fd, CERTCertificate **certs,
			 unsigned int *numCerts, unsigned int maxNumCerts)
{
    sslSocket *ss;
    ssl3CertNode* cur;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificateChain",
		 SSL_GETPID(), fd));
	return SECFailure;
    }
    if (!ss->opt.useSecurity)
	return SECFailure;

    if (ss->sec.peerCert == NULL) {
      *numCerts = 0;
      return SECSuccess;
    }

    *numCerts = 1;  /* for the leaf certificate */
    if (maxNumCerts > 0)
	certs[0] = CERT_DupCertificate(ss->sec.peerCert);

    for (cur = ss->ssl3.peerCertChain; cur; cur = cur->next) {
	if (*numCerts < maxNumCerts)
	    certs[*numCerts] = CERT_DupCertificate(cur->cert);
	(*numCerts)++;
    }

    return SECSuccess;
}
예제 #14
0
/* For SSLv2, does nothing but return an error.
** For SSLv3, flushes SID cache entry (if requested),
** and then starts new client hello or hello request.
** Acquires and releases HandshakeLock.
*/
SECStatus
SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache)
{
    sslSocket *ss;
    SECStatus  rv;
    
    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd));
	return SECFailure;
    }

    if (!ss->opt.useSecurity)
	return SECSuccess;
    
    ssl_Get1stHandshakeLock(ss);

    /* SSL v2 protocol does not support subsequent handshakes. */
    if (ss->version < SSL_LIBRARY_VERSION_3_0) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    } else {
	ssl_GetSSL3HandshakeLock(ss);
	rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
	ssl_ReleaseSSL3HandshakeLock(ss);
    }

    ssl_Release1stHandshakeLock(ss);

    return rv;
}
예제 #15
0
/* Acquires and releases HandshakeLock.
*/
SECStatus
SSL_ResetHandshake(PRFileDesc *s, PRBool asServer)
{
    sslSocket *ss;
    SECStatus status;
    PRNetAddr addr;

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

    /* Don't waste my time */
    if (!ss->opt.useSecurity)
	return SECSuccess;

    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    /* Reset handshake state */
    ssl_Get1stHandshakeLock(ss);

    ss->firstHsDone = PR_FALSE;
    if ( asServer ) {
	ss->handshake = ssl2_BeginServerHandshake;
	ss->handshaking = sslHandshakingAsServer;
    } else {
	ss->handshake = ssl2_BeginClientHandshake;
	ss->handshaking = sslHandshakingAsClient;
    }
    ss->nextHandshake       = 0;
    ss->securityHandshake   = 0;

    ssl_GetRecvBufLock(ss);
    status = ssl_InitGather(&ss->gs);
    ssl_ReleaseRecvBufLock(ss);

    ssl_GetSSL3HandshakeLock(ss);

    /*
    ** Blow away old security state and get a fresh setup.
    */
    ssl_GetXmitBufLock(ss); 
    ssl_ResetSecurityInfo(&ss->sec, PR_TRUE);
    status = ssl_CreateSecurityInfo(ss);
    ssl_ReleaseXmitBufLock(ss); 

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    if (!ss->TCPconnected)
	ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));

    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);

    return status;
}
예제 #16
0
/* Try to make progress on an SSL handshake by attempting to read the 
** next handshake from the peer, and sending any responses.
** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK  if it cannot 
** read the next handshake from the underlying socket.
** For SSLv2, returns when handshake is complete or fatal error occurs.
** For SSLv3, returns when handshake is complete, or application data has
** arrived that must be taken by application before handshake can continue, 
** or a fatal error occurs.
** Application should use handshake completion callback to tell which. 
*/
SECStatus
SSL_ForceHandshake(PRFileDesc *fd)
{
    sslSocket *ss;
    SECStatus  rv = SECFailure;

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

    /* Don't waste my time */
    if (!ss->opt.useSecurity) 
    	return SECSuccess;

    if (!ssl_SocketIsBlocking(ss)) {
	ssl_GetXmitBufLock(ss);
	if (ss->pendingBuf.len != 0) {
	    int sent = ssl_SendSavedWriteData(ss);
	    if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {
		ssl_ReleaseXmitBufLock(ss);
		return SECFailure;
	    }
	}
	ssl_ReleaseXmitBufLock(ss);
    }

    ssl_Get1stHandshakeLock(ss);

    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
	int gatherResult;

    	ssl_GetRecvBufLock(ss);
	gatherResult = ssl3_GatherCompleteHandshake(ss, 0);
	ssl_ReleaseRecvBufLock(ss);
	if (gatherResult > 0) {
	    rv = SECSuccess;
	} else if (gatherResult == 0) {
	    PORT_SetError(PR_END_OF_FILE_ERROR);
	} else if (gatherResult == SECWouldBlock) {
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
	}
    } else if (!ss->firstHsDone) {
	rv = ssl_Do1stHandshake(ss);
    } else {
	/* tried to force handshake on an SSL 2 socket that has 
	** already completed the handshake. */
    	rv = SECSuccess;	/* just pretend we did it. */
    }

    ssl_Release1stHandshakeLock(ss);

    return rv;
}
예제 #17
0
/* Public deprecated function */
SECStatus
SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
                            SSLKEAType certType)
{
    sslSocket *ss;
    SECStatus rv;

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

    switch (certType) {
        case ssl_kea_rsa:
            rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_decrypt, scts);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_rsa_sign, scts);

        case ssl_kea_dh:
            return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_dsa, scts);

        case ssl_kea_ecdh:
            rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdsa, scts);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            rv = ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_rsa, scts);
            if (rv != SECSuccess) {
                return SECFailure;
            }
            return ssl_SetSignedTimestampsInSlot(ss, ssl_auth_ecdh_ecdsa, scts);

        default:
            SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps",
                     SSL_GETPID(), fd));
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
    }
}
예제 #18
0
/* This function is called at the beginning of a handshake to ensure that at
 * least one SSL/TLS version is enabled. */
static SECStatus
ssl_CheckConfigSanity(sslSocket *ss)
{
    if (SSL_ALL_VERSIONS_DISABLED(&ss->vrange)) {
        SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.",
                 SSL_GETPID(), ss->fd));
        PORT_SetError(SSL_ERROR_SSL_DISABLED);
        return SECFailure;
    }
    return SECSuccess;
}
예제 #19
0
/* NEED LOCKS IN HERE.  */
SECStatus 
SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
{
    sslSocket *ss;

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

    ss->pkcs11PinArg = arg;
    return SECSuccess;
}
예제 #20
0
/* NEED LOCKS IN HERE.  */
CERTCertificate *
SSL_PeerCertificate(PRFileDesc *fd)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
		 SSL_GETPID(), fd));
	return 0;
    }
    if (ss->opt.useSecurity && ss->sec.peerCert) {
	return CERT_DupCertificate(ss->sec.peerCert);
    }
    return 0;
}
예제 #21
0
SECStatus
SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
                              SSLPreliminaryChannelInfo *info,
                              PRUintn len)
{
    sslSocket *ss;
    SSLPreliminaryChannelInfo inf;

    /* 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_GetPreliminaryChannelInfo",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

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

    inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
    inf.protocolVersion = ss->version;
    inf.cipherSuite = ss->ssl3.hs.cipher_suite;
    inf.canSendEarlyData = !ss->sec.isServer &&
                           (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
                            ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted);
    /* We shouldn't be able to send early data if the handshake is done. */
    PORT_Assert(!ss->firstHsDone || !inf.canSendEarlyData);

    if (ss->sec.ci.sid &&
        (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
         ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted)) {
        inf.maxEarlyDataSize =
            ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
    } else {
        inf.maxEarlyDataSize = 0;
    }

    memcpy(info, &inf, inf.length);
    return SECSuccess;
}
예제 #22
0
SECStatus
SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, 
                                 SSLExtensionType extId,
                                 PRBool *pYes)
{
  /* some decisions derived from SSL_GetChannelInfo */
  sslSocket * sslsocket = NULL;
  PRBool enoughFirstHsDone = PR_FALSE;

  if (!pYes) {
    PORT_SetError(SEC_ERROR_INVALID_ARGS);
    return SECFailure;
  }

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

  *pYes = PR_FALSE;

  if (sslsocket->firstHsDone) {
    enoughFirstHsDone = PR_TRUE;
  } else if (sslsocket->ssl3.initialized && ssl3_CanFalseStart(sslsocket)) {
    enoughFirstHsDone = PR_TRUE;
  }

  /* according to public API SSL_GetChannelInfo, this doesn't need a lock */
  if (sslsocket->opt.useSecurity && enoughFirstHsDone) {
    if (sslsocket->ssl3.initialized) { /* SSL3 and TLS */
      /* now we know this socket went through ssl3_InitState() and
       * ss->xtnData got initialized, which is the only member accessed by
       * ssl3_ExtensionNegotiated();
       * Member xtnData appears to get accessed in functions that handle
       * the handshake (hello messages and extension sending),
       * therefore the handshake lock should be sufficient.
       */
      ssl_GetSSL3HandshakeLock(sslsocket);
      *pYes = ssl3_ExtensionNegotiated(sslsocket, extId);
      ssl_ReleaseSSL3HandshakeLock(sslsocket);
    }
  }

  return SECSuccess;
}
예제 #23
0
/* For more info see ssl.h */
SECStatus 
SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func,
                        void *arg)
{
    sslSocket *ss;

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

    ss->sniSocketConfig = func;
    ss->sniSocketConfigArg = arg;
    return SECSuccess;
}
예제 #24
0
/* NEED LOCKS IN HERE.  */
SECStatus 
SSL_GetClientAuthDataHook(PRFileDesc *s, SSLGetClientAuthData func,
			      void *arg)
{
    sslSocket *ss;

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

    ss->getClientAuthData = func;
    ss->getClientAuthDataArg = arg;
    return SECSuccess;
}
예제 #25
0
/* NEED LOCKS IN HERE.  */
SECStatus
SSL_AuthCertificateHook(PRFileDesc *s, SSLAuthCertificate func, void *arg)
{
    sslSocket *ss;

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

    ss->authCertificate = func;
    ss->authCertificateArg = arg;

    return SECSuccess;
}
예제 #26
0
SECStatus
SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg)
{
    sslSocket *ss;
    
    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    ss->handleBadCert = f;
    ss->badCertArg = arg;

    return SECSuccess;
}
예제 #27
0
파일: sslauth.c 프로젝트: agamdua/libjingle
SECStatus
SSL_SetClientChannelIDCallback(PRFileDesc *fd,
			       SSLClientChannelIDCallback callback,
			       void *arg) {
    sslSocket *ss = ssl_FindSocket(fd);

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

    ss->getChannelID = callback;
    ss->getChannelIDArg = arg;

    return SECSuccess;
}
예제 #28
0
/* NEED LOCKS IN HERE.  */
CERTCertificate *
SSL_LocalCertificate(PRFileDesc *fd)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in PeerCertificate",
		 SSL_GETPID(), fd));
	return NULL;
    }
    if (ss->opt.useSecurity) {
    	if (ss->sec.localCert) {
	    return CERT_DupCertificate(ss->sec.localCert);
	}
	if (ss->sec.ci.sid && ss->sec.ci.sid->localCert) {
	    return CERT_DupCertificate(ss->sec.ci.sid->localCert);
	}
    }
    return NULL;
}
예제 #29
0
SECStatus
ssl_SelfEncryptUnprotect(
    sslSocket *ss, const PRUint8 *in, unsigned int inLen,
    PRUint8 *out, unsigned int *outLen, unsigned int maxOutLen)
{
    PRUint8 keyName[SELF_ENCRYPT_KEY_NAME_LEN];
    PK11SymKey *encKey;
    PK11SymKey *macKey;
    SECStatus rv;

    /* Get session ticket keys. */
    rv = ssl_GetSelfEncryptKeys(ss, keyName, &encKey, &macKey);
    if (rv != SECSuccess) {
        SSL_DBG(("%d: SSL[%d]: Unable to get/generate self-encrypt keys.",
                 SSL_GETPID(), ss->fd));
        return SECFailure;
    }

    return ssl_SelfEncryptUnprotectInt(encKey, macKey, keyName,
                                       in, inLen, out, outLen, maxOutLen);
}
예제 #30
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;
}