38 const int minLengthClient, minLengthServer;
43 static const EXT_CHECK_INFO extCheckInfoTbl[] = {
51 "server name indication" },
73 "client certificate URL" },
105 "OCSP status request" },
134 "cert-type (OpenPGP keying)" },
141 "ECDH/ECDSA curve ID" },
148 "ECDH/ECDSA point format" },
163 "signature algorithm" },
189 "secure renegotiation" },
202 #define RENEG_EXT_SIZE 5
203 #define RENEG_EXT_DATA "\xFF\x01\x00\x01\x00"
240 static const MAP_TABLE curveSizeTbl[] = {
250 #ifdef CONFIG_SUITEB_TESTS
263 *extErrorInfoSet =
FALSE;
273 status = listLen = readUint16( stream );
277 listLen < UINT16_SIZE || listLen > 256 || \
284 int value, curveID, curveSize;
286 status = value = readUint16( stream );
289 status = mapValue( value, &curveID, curveIDTbl,
293 status = mapValue( curveID, &curveSize, curveSizeTbl,
299 const int suiteBinfo =
\
311 #ifdef CONFIG_SUITEB_TESTS
312 if( suiteBTestValue == SUITEB_TEST_BOTHCURVES )
326 if( curveSize != keySize )
332 preferredCurveID = curveID;
334 #ifdef CONFIG_SUITEB_TESTS
337 if( suiteBTestValue == SUITEB_TEST_BOTHCURVES && curvesSeen != 3 )
339 *extErrorInfoSet =
TRUE;
342 "Supported elliptic curves extension should have "
343 "contained both P256 and P384 but didn't" ) );
347 *preferredCurveIdPtr = preferredCurveID;
391 static const MAP_TABLE curveSizeTbl[] = {
398 #ifdef CONFIG_SUITEB_TESTS
411 *extErrorInfoSet =
FALSE;
414 status = listLen = readUint16( stream );
417 if( listLen != extLength - UINT16_SIZE || \
418 listLen < 1 + 1 || listLen > 64 + 64 || \
419 ( listLen % UINT16_SIZE ) != 0 )
424 return( sSkip( stream, listLen ) );
436 return( sSkip( stream, listLen ) );
446 status = mapValue( keySize, &hashType, curveSizeTbl,
459 for( ; listLen > 0; listLen -= 1 + 1 )
466 hashAlgo = sgetc( stream );
467 status = sigAlgo = sgetc( stream );
477 #ifdef CONFIG_SUITEB_TESTS
478 if( suiteBTestValue == SUITEB_TEST_BOTHSIGALGOS )
491 if( hashType != hashAlgo )
501 handshakeInfo->keyexSigHashAlgoParam =
bitsToBytes( 384 );
508 *extErrorInfoSet =
TRUE;
511 "Signature algorithms extension should have "
512 "contained %sP384/SHA384 but didn't",
514 "P256/SHA256 and/or " :
"" ) );
516 #ifdef CONFIG_SUITEB_TESTS
519 if( suiteBTestValue == SUITEB_TEST_BOTHSIGALGOS && hashesSeen != 3 )
521 *extErrorInfoSet =
TRUE;
524 "Signature algortithms extension should have contained "
525 "both P256/SHA256 and P384/SHA384 but didn't" ) );
533 return( sSkip( stream, listLen ) );
554 REQUIRES( type >= 0 && type <= 65536 );
558 *extErrorInfoSet =
FALSE;
587 handshakeInfo->needSNIResponse =
TRUE;
589 status = listLen = readUint16( stream );
592 if( listLen != extLength - UINT16_SIZE || \
593 listLen < 1 + UINT16_SIZE || \
595 ( listLen % UINT16_SIZE ) != 0 )
599 return( sSkip( stream, listLen ) );
613 status = value = sgetc( stream );
628 status = processSupportedCurveID( sessionInfoPtr, stream,
629 extLength, &preferredCurveID,
644 handshakeInfo->disableECC =
TRUE;
646 handshakeInfo->eccCurveID = preferredCurveID;
663 status = sSkip( stream, extLength );
667 handshakeInfo->sendECCPointExtn =
TRUE;
673 return( processSignatureAlgos( sessionInfoPtr, handshakeInfo,
683 if( extLength != 1 || sgetc( stream ) != 0 )
689 handshakeInfo->needRenegResponse =
TRUE;
697 status = sSkip( stream, extLength );
717 int minPayloadLength = 1, extListLen, noExtensions,
status;
730 if( !
isServer( sessionInfoPtr ) && \
732 minPayloadLength = 0;
740 if( length < UINT16_SIZE + UINT16_SIZE + UINT16_SIZE + minPayloadLength )
744 "TLS hello contains %d bytes extraneous data", length ) );
746 status = extListLen = readUint16( stream );
751 "Invalid TLS extension information" ) );
753 if( extListLen != length - UINT16_SIZE )
757 "Invalid TLS extension data length %d, should be %d",
758 extListLen, length - UINT16_SIZE ) );
762 for( noExtensions = 0; stell( stream ) < endPos && \
766 const EXT_CHECK_INFO *extCheckInfoPtr = NULL;
774 type = readUint16( stream );
775 status = extLen = readUint16( stream );
781 "Invalid TLS extension list item header" ) );
783 for( i = 0; extCheckInfoTbl[ i ].type !=
CRYPT_ERROR && \
787 if( extCheckInfoTbl[ i ].type == type )
789 extCheckInfoPtr = &extCheckInfoTbl[ i ];
794 if( extCheckInfoPtr != NULL )
797 extCheckInfoPtr->minLengthClient : \
798 extCheckInfoPtr->minLengthServer;
805 "Received disallowed TLS %s extension from %s",
806 extCheckInfoPtr->typeName,
807 isServer( sessionInfoPtr ) ?
"server" :
"client" ) );
809 if( extLen < minLength || extLen > extCheckInfoPtr->maxLength )
813 "Invalid TLS %s extension length %d, should be "
814 "%d...%d", extCheckInfoPtr->typeName, extLen,
815 minLength, extCheckInfoPtr->maxLength ) );
818 DEBUG_PRINT((
"Read extension %s (%d), length %d.\n",
819 ( extCheckInfoPtr != NULL ) ? \
820 extCheckInfoPtr->typeName :
"<Unknown>", type, extLen ));
824 status = processExtension( sessionInfoPtr, handshakeInfo, stream,
825 type, extLen, &extErrorInfoSet );
828 if( extErrorInfoSet )
830 if( extCheckInfoPtr != NULL )
834 "Invalid TLS %s extension data",
835 extCheckInfoPtr->typeName ) );
839 "Invalid TLS extension data for extension "
843 if( noExtensions >= FAILSAFE_ITERATIONS_MED )
847 "Excessive number (%d) of TLS extensions encountered",
872 static
int writeSigHashAlgoList(
STREAM *stream )
879 static const SIG_HASH_INFO algoTbl[] = {
904 BYTE algoList[ 32 + 8 ];
905 int algoIndex = 0, i;
917 while( algoTbl[ i ].sigAlgo == sigAlgo && \
934 algoList[ algoIndex++ ] =
intToByte( algoTbl[ i ].tlsHashAlgoID );
935 algoList[ algoIndex++ ] =
intToByte( algoTbl[ i ].tlsSigAlgoID );
941 writeUint16( stream, algoIndex );
942 return( swrite( stream, algoList, algoIndex ) );
952 findSessionInfo( sessionInfoPtr->attributeList,
963 status = sNetParseURL( &urlInfo, serverNamePtr->value,
969 writeUint16( stream, 1 + UINT16_SIZE + urlInfo.
hostLen );
971 writeUint16( stream, urlInfo.
hostLen );
972 return( swrite( stream, urlInfo.host, urlInfo.
hostLen ) );
983 int serverNameExtLen =
DUMMY_INIT, sigHashHdrLen = 0, sigHashExtLen = 0;
993 sMemNullOpen( &nullStream );
994 status = writeServerName( &nullStream, sessionInfoPtr );
996 serverNameExtLen = stell( &nullStream );
997 sMemClose( &nullStream );
1005 sMemNullOpen( &nullStream );
1006 status = writeSigHashAlgoList( &nullStream );
1010 sigHashExtLen = stell( &nullStream );
1012 sMemClose( &nullStream );
1022 static const BYTE eccCurveInfo[] = {
1028 #ifdef CONFIG_SUITEB
1031 static const BYTE eccCurveSuiteB128Info[] = {
1034 static const BYTE eccCurveSuiteB256Info[] = {
1037 const int suiteBinfo =
\
1042 eccCurveInfoPtr = eccCurveSuiteB128Info;
1047 eccCurveInfoPtr = eccCurveSuiteB256Info;
1050 #ifdef CONFIG_SUITEB_TESTS
1053 if( suiteBTestValue == SUITEB_TEST_CLIINVALIDCURVE )
1055 static const BYTE eccCurveSuiteBInvalidInfo[] = {
1059 eccCurveInfoPtr = eccCurveSuiteBInvalidInfo;
1067 eccCurveInfoPtr = eccCurveInfo;
1070 eccInfoLen = UINT16_SIZE + UINT16_SIZE + \
1071 UINT16_SIZE + eccCurveTypeLen;
1072 eccInfoLen += UINT16_SIZE + UINT16_SIZE + 1 + 1;
1076 writeUint16( stream, UINT16_SIZE + UINT16_SIZE + serverNameExtLen + \
1077 RENEG_EXT_SIZE + sigHashHdrLen + sigHashExtLen + \
1080 writeUint16( stream, serverNameExtLen );
1081 status = writeServerName( stream, sessionInfoPtr );
1084 DEBUG_PRINT((
"Wrote extension server name indication (%d), length %d.\n",
1088 status = swrite( stream, RENEG_EXT_DATA, RENEG_EXT_SIZE );
1091 DEBUG_PRINT((
"Wrote extension secure renegotiation (%d), length 1.\n",
1094 if( sigHashExtLen > 0 )
1097 writeUint16( stream, sigHashExtLen );
1098 status = writeSigHashAlgoList( stream );
1101 DEBUG_PRINT((
"Wrote extension signature algorithm (%d), length %d.\n",
1104 stell( stream ) - sigHashExtLen, sigHashExtLen );
1106 if( eccInfoLen > 0 )
1110 writeUint16( stream, UINT16_SIZE + eccCurveTypeLen );
1111 writeUint16( stream, eccCurveTypeLen );
1112 status = swrite( stream, eccCurveInfoPtr, eccCurveTypeLen );
1115 DEBUG_PRINT((
"Wrote extension ECC curve type (%d), length %d.\n",
1118 stell( stream ) - ( UINT16_SIZE + eccCurveTypeLen ),
1119 UINT16_SIZE + eccCurveTypeLen );
1123 writeUint16( stream, 1 + 1 );
1125 status = sputc( stream, 0 );
1128 DEBUG_PRINT((
"Wrote extension ECC point format (%d), length %d.\n",
1139 int extListLen = 0,
status;
1145 if(
isEccAlgo( handshakeInfo->keyexAlgo ) && \
1146 handshakeInfo->sendECCPointExtn )
1147 extListLen += UINT16_SIZE + UINT16_SIZE + 1 + 1;
1148 if( handshakeInfo->needSNIResponse )
1150 if( handshakeInfo->needRenegResponse )
1151 extListLen += RENEG_EXT_SIZE;
1152 if( extListLen <= 0 )
1159 writeUint16( stream, extListLen );
1172 if( handshakeInfo->needSNIResponse )
1175 status = writeUint16( stream, 0 );
1178 DEBUG_PRINT((
"Wrote extension extension server name indication (%d), "
1185 if( handshakeInfo->needRenegResponse )
1187 status = swrite( stream, RENEG_EXT_DATA, RENEG_EXT_SIZE );
1190 DEBUG_PRINT((
"Wrote extension secure renegotiation (%d), length 1.\n",
1199 if(
isEccAlgo( handshakeInfo->keyexAlgo ) && \
1200 handshakeInfo->sendECCPointExtn )
1203 writeUint16( stream, 1 + 1 );
1205 status = sputc( stream, 0 );
1208 DEBUG_PRINT((
"Wrote extension ECC point format (%d), length %d.\n",