4040import org .bouncycastle .tls .crypto .TlsEncryptor ;
4141import org .bouncycastle .tls .crypto .TlsHash ;
4242import org .bouncycastle .tls .crypto .TlsHashOutputStream ;
43+ import org .bouncycastle .tls .crypto .TlsHybridAgreement ;
4344import org .bouncycastle .tls .crypto .TlsKemConfig ;
4445import org .bouncycastle .tls .crypto .TlsSecret ;
4546import org .bouncycastle .tls .crypto .TlsStreamSigner ;
@@ -1149,7 +1150,7 @@ public static void addIfSupported(Vector supportedAlgs, TlsCrypto crypto, Signat
11491150
11501151 public static void addIfSupported (Vector supportedGroups , TlsCrypto crypto , int namedGroup )
11511152 {
1152- if (crypto . hasNamedGroup ( namedGroup ))
1153+ if (isSupportedNamedGroup ( crypto , namedGroup ))
11531154 {
11541155 supportedGroups .addElement (Integers .valueOf (namedGroup ));
11551156 }
@@ -4449,6 +4450,17 @@ public static boolean isSupportedKeyExchange(TlsCrypto crypto, int keyExchangeAl
44494450 }
44504451 }
44514452
4453+ public static boolean isSupportedNamedGroup (TlsCrypto crypto , int namedGroup )
4454+ {
4455+ if (!NamedGroup .refersToASpecificHybrid (namedGroup ))
4456+ {
4457+ return crypto .hasNamedGroup (namedGroup );
4458+ }
4459+
4460+ return crypto .hasNamedGroup (NamedGroup .getHybridFirst (namedGroup ))
4461+ && crypto .hasNamedGroup (NamedGroup .getHybridSecond (namedGroup ));
4462+ }
4463+
44524464 static boolean hasAnyRSASigAlgs (TlsCrypto crypto )
44534465 {
44544466 return crypto .hasSignatureAlgorithm (SignatureAlgorithm .rsa )
@@ -5362,45 +5374,79 @@ private static void collectKeyShares(TlsCrypto crypto, int[] supportedGroups, Ve
53625374 int supportedGroup = supportedGroups [i ];
53635375 Integer supportedGroupElement = Integers .valueOf (supportedGroup );
53645376
5365- if (!keyShareGroups .contains (supportedGroupElement )
5366- || clientAgreements .containsKey (supportedGroupElement )
5367- || !crypto .hasNamedGroup (supportedGroup ))
5377+ if (!keyShareGroups .contains (supportedGroupElement ) ||
5378+ clientAgreements .containsKey (supportedGroupElement ))
53685379 {
53695380 continue ;
53705381 }
53715382
5372- TlsAgreement agreement = null ;
5373- if (NamedGroup .refersToAnECDHCurve (supportedGroup ))
5383+ TlsAgreement agreement = createKeyShare (crypto , supportedGroup , false );
5384+ if (agreement != null )
5385+ {
5386+ byte [] key_exchange = agreement .generateEphemeral ();
5387+ KeyShareEntry clientShare = new KeyShareEntry (supportedGroup , key_exchange );
5388+
5389+ clientShares .addElement (clientShare );
5390+ clientAgreements .put (supportedGroupElement , agreement );
5391+ }
5392+ }
5393+ }
5394+
5395+ static TlsAgreement createKeyShare (TlsCrypto crypto , int keyShareGroup , boolean isServer )
5396+ {
5397+ if (!NamedGroup .refersToASpecificHybrid (keyShareGroup ))
5398+ {
5399+ return createKeyShareSimple (crypto , keyShareGroup , isServer );
5400+ }
5401+
5402+ int hybridFirst = NamedGroup .getHybridFirst (keyShareGroup );
5403+ TlsAgreement firstAgreement = createKeyShareSimple (crypto , hybridFirst , isServer );
5404+ if (firstAgreement == null )
5405+ {
5406+ return null ;
5407+ }
5408+
5409+ int hybridSecond = NamedGroup .getHybridSecond (keyShareGroup );
5410+ TlsAgreement secondAgreement = createKeyShareSimple (crypto , hybridSecond , isServer );
5411+ if (secondAgreement == null )
5412+ {
5413+ return null ;
5414+ }
5415+
5416+ int peerValueSplit = isServer
5417+ ? NamedGroup .getHybridSplitClientShare (hybridFirst )
5418+ : NamedGroup .getHybridSplitServerShare (hybridFirst );
5419+
5420+ return new TlsHybridAgreement (crypto , firstAgreement , secondAgreement , peerValueSplit );
5421+ }
5422+
5423+ private static TlsAgreement createKeyShareSimple (TlsCrypto crypto , int keyShareGroup , boolean isServer )
5424+ {
5425+ if (crypto .hasNamedGroup (keyShareGroup ))
5426+ {
5427+ if (NamedGroup .refersToAnECDHCurve (keyShareGroup ))
53745428 {
53755429 if (crypto .hasECDHAgreement ())
53765430 {
5377- agreement = crypto .createECDomain (new TlsECConfig (supportedGroup )).createECDH ();
5431+ return crypto .createECDomain (new TlsECConfig (keyShareGroup )).createECDH ();
53785432 }
53795433 }
5380- else if (NamedGroup .refersToASpecificFiniteField (supportedGroup ))
5434+ else if (NamedGroup .refersToASpecificFiniteField (keyShareGroup ))
53815435 {
53825436 if (crypto .hasDHAgreement ())
53835437 {
5384- agreement = crypto .createDHDomain (new TlsDHConfig (supportedGroup , true )).createDH ();
5438+ return crypto .createDHDomain (new TlsDHConfig (keyShareGroup , true )).createDH ();
53855439 }
53865440 }
5387- else if (NamedGroup .refersToASpecificKem (supportedGroup ))
5441+ else if (NamedGroup .refersToASpecificKem (keyShareGroup ))
53885442 {
53895443 if (crypto .hasKemAgreement ())
53905444 {
5391- agreement = crypto .createKemDomain (new TlsKemConfig (supportedGroup , false )).createKem ();
5445+ return crypto .createKemDomain (new TlsKemConfig (keyShareGroup , isServer )).createKem ();
53925446 }
53935447 }
5394-
5395- if (null != agreement )
5396- {
5397- byte [] key_exchange = agreement .generateEphemeral ();
5398- KeyShareEntry clientShare = new KeyShareEntry (supportedGroup , key_exchange );
5399-
5400- clientShares .addElement (clientShare );
5401- clientAgreements .put (supportedGroupElement , agreement );
5402- }
54035448 }
5449+ return null ;
54045450 }
54055451
54065452 static KeyShareEntry selectKeyShare (Vector clientShares , int keyShareGroup )
@@ -5427,25 +5473,10 @@ static KeyShareEntry selectKeyShare(TlsCrypto crypto, ProtocolVersion negotiated
54275473
54285474 int group = clientShare .getNamedGroup ();
54295475
5430- if (!NamedGroup .canBeNegotiated (group , negotiatedVersion ))
5431- {
5432- continue ;
5433- }
5434-
5435- if (!Arrays .contains (serverSupportedGroups , group ) ||
5436- !Arrays .contains (clientSupportedGroups , group ))
5437- {
5438- continue ;
5439- }
5440-
5441- if (!crypto .hasNamedGroup (group ))
5442- {
5443- continue ;
5444- }
5445-
5446- if ((NamedGroup .refersToAnECDHCurve (group ) && crypto .hasECDHAgreement ()) ||
5447- (NamedGroup .refersToASpecificFiniteField (group ) && crypto .hasDHAgreement ()) ||
5448- (NamedGroup .refersToASpecificKem (group ) && crypto .hasKemAgreement ()))
5476+ if (NamedGroup .canBeNegotiated (group , negotiatedVersion ) &&
5477+ Arrays .contains (serverSupportedGroups , group ) &&
5478+ Arrays .contains (clientSupportedGroups , group ) &&
5479+ supportsKeyShareGroup (crypto , group ))
54495480 {
54505481 return clientShare ;
54515482 }
@@ -5463,30 +5494,46 @@ static int selectKeyShareGroup(TlsCrypto crypto, ProtocolVersion negotiatedVersi
54635494 {
54645495 int group = clientSupportedGroups [i ];
54655496
5466- if (!NamedGroup .canBeNegotiated (group , negotiatedVersion ))
5497+ if (NamedGroup .canBeNegotiated (group , negotiatedVersion ) &&
5498+ Arrays .contains (serverSupportedGroups , group ) &&
5499+ supportsKeyShareGroup (crypto , group ))
54675500 {
5468- continue ;
5501+ return group ;
54695502 }
5503+ }
5504+ }
5505+ return -1 ;
5506+ }
54705507
5471- if (!Arrays .contains (serverSupportedGroups , group ))
5472- {
5473- continue ;
5474- }
5508+ private static boolean supportsKeyShareGroup (TlsCrypto crypto , int keyShareGroup )
5509+ {
5510+ if (!NamedGroup .refersToASpecificHybrid (keyShareGroup ))
5511+ {
5512+ return supportsKeyShareGroupSimple (crypto , keyShareGroup );
5513+ }
54755514
5476- if (!crypto .hasNamedGroup (group ))
5477- {
5478- continue ;
5479- }
5515+ return supportsKeyShareGroupSimple (crypto , NamedGroup .getHybridFirst (keyShareGroup ))
5516+ && supportsKeyShareGroupSimple (crypto , NamedGroup .getHybridSecond (keyShareGroup ));
5517+ }
54805518
5481- if ((NamedGroup .refersToAnECDHCurve (group ) && crypto .hasECDHAgreement ()) ||
5482- (NamedGroup .refersToASpecificFiniteField (group ) && crypto .hasDHAgreement ()) ||
5483- (NamedGroup .refersToASpecificKem (group ) && crypto .hasKemAgreement ()))
5484- {
5485- return group ;
5486- }
5519+ private static boolean supportsKeyShareGroupSimple (TlsCrypto crypto , int keyShareGroup )
5520+ {
5521+ if (crypto .hasNamedGroup (keyShareGroup ))
5522+ {
5523+ if (NamedGroup .refersToAnECDHCurve (keyShareGroup ))
5524+ {
5525+ return crypto .hasECDHAgreement ();
5526+ }
5527+ else if (NamedGroup .refersToASpecificFiniteField (keyShareGroup ))
5528+ {
5529+ return crypto .hasDHAgreement ();
5530+ }
5531+ else if (NamedGroup .refersToASpecificKem (keyShareGroup ))
5532+ {
5533+ return crypto .hasKemAgreement ();
54875534 }
54885535 }
5489- return - 1 ;
5536+ return false ;
54905537 }
54915538
54925539 static byte [] readEncryptedPMS (TlsContext context , InputStream input ) throws IOException
0 commit comments