cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ssl_cli.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib SSL v3/TLS Client Management *
4 * Copyright Peter Gutmann 1998-2010 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "misc_rw.h"
11  #include "session.h"
12  #include "ssl.h"
13 #else
14  #include "crypt.h"
15  #include "enc_dec/misc_rw.h"
16  #include "session/session.h"
17  #include "session/ssl.h"
18 #endif /* Compiler-specific includes */
19 
20 /* Testing the SSL/TLS code gets a bit complicated because in the presence
21  of the session cache every session after the first one will be a resumed
22  session. To deal with this we disable the client-side session cache in
23  the VC++ 6 debug build */
24 
25 #if defined( __WINDOWS__ ) && defined( _MSC_VER ) && ( _MSC_VER == 1200 ) && \
26  !defined( NDEBUG ) && 1
27  #define NO_SESSION_CACHE
28 #endif /* VC++ 6.0 debug build */
29 
30 #ifdef USE_SSL
31 
32 /****************************************************************************
33 * *
34 * Utility Functions *
35 * *
36 ****************************************************************************/
37 
38 #ifdef CONFIG_SUITEB
39 
40 /* For Suite B the first suite must be ECDHE/AES128-GCM/SHA256 or
41  ECDHE/AES256-GCM/SHA384 depending on the security level and the second
42  suite, at the 128-bit security level, must be ECDHE/AES256-GCM/SHA384 */
43 
44 CHECK_RETVAL_BOOL \
45 static int checkSuiteBSelection( IN_RANGE( SSL_FIRST_VALID_SUITE, \
46  SSL_LAST_SUITE - 1 ) \
47  const int cipherSuite,
48  const int flags,
49  const BOOLEAN isFirstSuite )
50  {
51  REQUIRES( cipherSuite >= SSL_FIRST_VALID_SUITE && \
52  cipherSuite < SSL_LAST_SUITE );
53  REQUIRES( ( flags & ~( SSL_PFLAG_SUITEB ) ) == 0 );
54 
55  if( isFirstSuite )
56  {
57  switch( flags )
58  {
60  if( cipherSuite == TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 )
61  return( TRUE );
62  break;
63 
65  if( cipherSuite == TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 )
66  return( TRUE );
67  break;
68 
69  default:
70  retIntError();
71  }
72  }
73  else
74  {
75  switch( flags )
76  {
78  if( cipherSuite == TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 )
79  return( TRUE );
80  break;
81 
83  /* For the 256-bit level there are no further requirements */
84  return( TRUE );
85 
86  default:
87  retIntError();
88  }
89  }
90 
91  return( FALSE );
92  }
93 #endif /* CONFIG_SUITEB */
94 
95 /* Encode a list of available algorithms */
96 
98 static int writeCipherSuiteList( INOUT STREAM *stream,
99  const BOOLEAN usePSK,
100  const BOOLEAN useTLS12,
101  const BOOLEAN isServer,
102  IN_FLAGS_Z( SSL ) const int suiteBinfo )
103  {
104  const CIPHERSUITE_INFO **cipherSuiteInfo;
105  int availableSuites[ 32 + 8 ], cipherSuiteCount = 0, suiteIndex;
106  int cipherSuiteInfoSize, status;
107 #ifdef CONFIG_SUITEB
108  int suiteNo = 0;
109 #endif /* CONFIG_SUITEB */
110 
111  assert( isWritePtr( stream, sizeof( STREAM ) ) );
112 
113 #ifdef CONFIG_SUITEB
114  REQUIRES( suiteBinfo >= SSL_PFLAG_NONE && suiteBinfo < SSL_PFLAG_MAX );
115 #endif /* CONFIG_SUITEB */
116 
117  /* Get the information for the supported cipher suites */
118  status = getCipherSuiteInfo( &cipherSuiteInfo, &cipherSuiteInfoSize,
119  isServer );
120  if( cryptStatusError( status ) )
121  return( status );
122 
123  /* Walk down the list of algorithms (and the corresponding cipher
124  suites) remembering each one that's available for use */
125  for( suiteIndex = 0;
126  suiteIndex < cipherSuiteInfoSize && \
127  cipherSuiteInfo[ suiteIndex ]->cipherSuite != SSL_NULL_WITH_NULL && \
128  cipherSuiteCount < 32;
129  /* No action */ )
130  {
131  const CIPHERSUITE_INFO *cipherSuiteInfoPtr = cipherSuiteInfo[ suiteIndex ];
132  const CRYPT_ALGO_TYPE keyexAlgo = cipherSuiteInfoPtr->keyexAlgo;
133  const CRYPT_ALGO_TYPE cryptAlgo = cipherSuiteInfoPtr->cryptAlgo;
134  const CRYPT_ALGO_TYPE authAlgo = cipherSuiteInfoPtr->authAlgo;
135  const CRYPT_ALGO_TYPE macAlgo = cipherSuiteInfoPtr->macAlgo;
136  const int suiteFlags = cipherSuiteInfoPtr->flags;
137 
138  /* Make sure that the cipher suite is appropriate for SuiteB use if
139  necessary */
140 #ifdef CONFIG_SUITEB
141  if( suiteNo == 0 || suiteNo == 1 )
142  {
143  if( !checkSuiteBSelection( cipherSuiteInfoPtr->cipherSuite,
144  ( suiteBinfo == 0 ) ? \
145  SSL_PFLAG_SUITEB_128 : suiteBinfo,
146  ( suiteNo == 0 ) ? TRUE : FALSE ) )
147  {
148  suiteIndex++;
149  continue;
150  }
151  suiteNo++;
152  }
153 #endif /* CONFIG_SUITEB */
154 
155  /* If it's a PSK or TLS 1.2 suite but we're not using PSK or a TLS
156  1.2 handshake, skip it */
157  if( ( ( suiteFlags & CIPHERSUITE_FLAG_PSK ) && !usePSK ) || \
158  ( ( suiteFlags & CIPHERSUITE_FLAG_TLS12 ) && !useTLS12 ) )
159  {
160  suiteIndex++;
161  continue;
162  }
163 
164  /* If the keyex algorithm for this suite isn't enabled for this
165  build of cryptlib, skip all suites that use it. We have to
166  explicitly exclude the special case where there's no keyex
167  algorithm in order to accomodate the bare TLS-PSK suites (used
168  without DH/ECDH or RSA), whose keyex mechanism is pure PSK */
169  if( keyexAlgo != CRYPT_ALGO_NONE && !algoAvailable( keyexAlgo ) )
170  {
171  while( cipherSuiteInfo[ suiteIndex ]->keyexAlgo == keyexAlgo && \
172  suiteIndex < cipherSuiteInfoSize )
173  suiteIndex++;
174  ENSURES( suiteIndex < cipherSuiteInfoSize );
175  continue;
176  }
177 
178  /* If the bulk encryption algorithm or MAC algorithm for this suite
179  isn't enabled for this build of cryptlib, skip all suites that
180  use it */
181  if( !algoAvailable( cryptAlgo ) )
182  {
183  while( cipherSuiteInfo[ suiteIndex ]->cryptAlgo == cryptAlgo && \
184  suiteIndex < cipherSuiteInfoSize )
185  suiteIndex++;
186  ENSURES( suiteIndex < cipherSuiteInfoSize );
187  continue;
188  }
189  if( !algoAvailable( macAlgo ) )
190  {
191  while( cipherSuiteInfo[ suiteIndex ]->macAlgo == macAlgo && \
192  suiteIndex < cipherSuiteInfoSize )
193  suiteIndex++;
194  ENSURES( suiteIndex < cipherSuiteInfoSize );
195  continue;
196  }
197 
198  /* The suite is supported, remember it. In theory there's only a
199  single combination of the various algorithms present, but these
200  can be subsetted into different key sizes (because they're there,
201  that's why) so we have to iterate the recording of available
202  suites instead of just assigning a single value on match */
203  while( cipherSuiteInfo[ suiteIndex ]->keyexAlgo == keyexAlgo && \
204  cipherSuiteInfo[ suiteIndex ]->authAlgo == authAlgo && \
205  cipherSuiteInfo[ suiteIndex ]->cryptAlgo == cryptAlgo && \
206  cipherSuiteInfo[ suiteIndex ]->macAlgo == macAlgo && \
207  cipherSuiteCount < 32 && suiteIndex < cipherSuiteInfoSize )
208  {
209  availableSuites[ cipherSuiteCount++ ] = \
210  cipherSuiteInfo[ suiteIndex++ ]->cipherSuite;
211 #ifdef CONFIG_SUITEB
212  if( suiteNo == 0 || suiteNo == 1 )
213  break; /* Suite B has special requirements for initial suites */
214 #endif /* CONFIG_SUITEB */
215  }
216  ENSURES( suiteIndex < cipherSuiteInfoSize );
217  ENSURES( cipherSuiteCount < 32 );
218  }
219  ENSURES( suiteIndex < cipherSuiteInfoSize );
220  ENSURES( cipherSuiteCount > 0 && cipherSuiteCount < 32 );
221 
222  /* Encode the list of available cipher suites */
223  status = writeUint16( stream, cipherSuiteCount * UINT16_SIZE );
224  for( suiteIndex = 0;
225  cryptStatusOK( status ) && suiteIndex < cipherSuiteCount;
226  suiteIndex++ )
227  status = writeUint16( stream, availableSuites[ suiteIndex ] );
228 
229  return( status );
230  }
231 
232 /* Process a server's DH/ECDH key agreement data:
233 
234  DH:
235  uint16 dh_pLen
236  byte[] dh_p
237  uint16 dh_gLen
238  byte[] dh_g
239  uint16 dh_YsLen
240  byte[] dh_Ys
241  ECDH:
242  byte curveType
243  uint16 namedCurve
244  uint8 ecPointLen -- NB uint8 not uint16
245  byte[] ecPoint */
246 
247 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
248 static int processServerKeyex( INOUT STREAM *stream,
249  OUT KEYAGREE_PARAMS *keyAgreeParams,
250  OUT_HANDLE_OPT CRYPT_CONTEXT *dhContextPtr,
251  const BOOLEAN isECC )
252  {
253  void *keyData;
254  const int keyDataOffset = stell( stream );
255  int keyDataLength, dummy, status;
256 
257  assert( isWritePtr( stream, sizeof( STREAM ) ) );
258  assert( isWritePtr( keyAgreeParams, sizeof( KEYAGREE_PARAMS ) ) );
259  assert( isWritePtr( dhContextPtr, sizeof( CRYPT_CONTEXT ) ) );
260 
261  /* Clear return values */
262  memset( keyAgreeParams, 0, sizeof( KEYAGREE_PARAMS ) );
263  *dhContextPtr = CRYPT_ERROR;
264 
265  /* Read the server DH/ECDH public key data */
266  if( isECC )
267  {
268  ( void ) sgetc( stream );
269  status = readUint16( stream );
270  }
271  else
272  {
273  status = readInteger16UChecked( stream, NULL, &dummy,
276  if( cryptStatusOK( status ) )
277  status = readInteger16U( stream, NULL, &dummy, 1,
279  }
280  if( cryptStatusError( status ) )
281  return( status );
282 
283  /* Create a DH/ECDH context from the public key data. If it's an ECC
284  algorithm we set a dummy curve type, the actual value is determined
285  by the parameters sent by the server */
286  keyDataLength = stell( stream ) - keyDataOffset;
287  status = sMemGetDataBlockAbs( stream, keyDataOffset, &keyData,
288  keyDataLength );
289  if( cryptStatusOK( status ) )
290  {
291  status = initDHcontextSSL( dhContextPtr, keyData, keyDataLength,
292  CRYPT_UNUSED, isECC ? \
293  CRYPT_ECCCURVE_P256 /* Dummy */ : \
295  }
296  if( cryptStatusError( status ) )
297  return( status );
298 
299  /* Read the DH/ECDH public value */
300  if( isECC )
301  {
302  return( readEcdhValue( stream, keyAgreeParams->publicValue,
304  &keyAgreeParams->publicValueLen ) );
305  }
306  return( readInteger16UChecked( stream, keyAgreeParams->publicValue,
307  &keyAgreeParams->publicValueLen,
309  CRYPT_MAX_PKCSIZE ) );
310  }
311 
312 /****************************************************************************
313 * *
314 * Client-side Connect Functions *
315 * *
316 ****************************************************************************/
317 
318 /* Perform the initial part of the handshake with the server */
319 
320 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
321 static int beginClientHandshake( INOUT SESSION_INFO *sessionInfoPtr,
323  {
324 #ifndef NO_SESSION_CACHE
326 #endif /* NO_SESSION_CACHE */
327  STREAM *stream = &handshakeInfo->stream;
328  SCOREBOARD_LOOKUP_RESULT lookupResult;
330  BYTE sentSessionID[ MAX_SESSIONID_SIZE + 8 ];
331  BOOLEAN sessionIDsent = FALSE;
332  int packetOffset, length, sentSessionIDlength = DUMMY_INIT, status;
333 
334  assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
335  assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
336 
337  /* Check whether we have (potentially) cached data available for the
338  server. If we've had the connection to the remote system provided
339  by the user (for example as an already-connected socket) then there
340  won't be any server name information present, so we can only
341  perform a session resume if we've established the connection
342  ourselves */
343 #ifndef NO_SESSION_CACHE
344  attributeListPtr = findSessionInfo( sessionInfoPtr->attributeList,
346  if( attributeListPtr != NULL )
347  {
348  status = lookupScoreboardEntry( sessionInfoPtr->sessionSSL->scoreboardInfoPtr,
349  SCOREBOARD_KEY_FQDN, attributeListPtr->value,
350  attributeListPtr->valueLength, &lookupResult );
351  if( !cryptStatusError( status ) )
352  {
353  /* We've got cached data for the server available, remember the
354  session ID so that we can send it to the server */
355  status = attributeCopyParams( handshakeInfo->sessionID,
357  &handshakeInfo->sessionIDlength,
358  lookupResult.key,
359  lookupResult.keySize );
360  ENSURES( cryptStatusOK( status ) );
361 
362  /* Make a copy of the session ID that we're sending so that we
363  can check it against what the server sends back to us later.
364  This isn't technically necessary, but if we request the reuse
365  of a session with ID X and the server comes back to us with a
366  response indicating we should reuse session Y then there's
367  something funny going on */
368  memcpy( sentSessionID, handshakeInfo->sessionID,
369  handshakeInfo->sessionIDlength );
370  sentSessionIDlength = handshakeInfo->sessionIDlength;
371  }
372  }
373 #endif /* NO_SESSION_CACHE */
374 
375  /* Get the nonce that's used to randomise all crypto ops */
376  setMessageData( &msgData, handshakeInfo->clientNonce, SSL_NONCE_SIZE );
378  &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
379  if( cryptStatusError( status ) )
380  return( status );
381 
382  /* Build the client hello packet:
383 
384  byte ID = SSL_HAND_CLIENT_HELLO
385  uint24 len
386  byte[2] version = { 0x03, 0x0n }
387  byte[32] nonce
388  byte sessIDlen = 0
389  [ byte[] sessID -- Omitted since len == 0 ]
390  uint16 suiteLen
391  uint16[] suite
392  byte coprLen = 1
393  byte[] copr = { 0x00 }
394  [ uint16 extListLen -- RFC 3546/RFC 4366
395  byte extType
396  uint16 extLen
397  byte[] extData ]
398 
399  Extensions present a bit of an interoperability problem on the client
400  side, if we use them then we have to add them to the client hello
401  before we know whether the server can handle them, and many servers
402  can't (this is particularly bad in cryptlib's case where it's used
403  with embedded systems, which have ancient and buggy SSL/TLS
404  implementations that are rarely if ever updated). A reasonable
405  compromise is to only enable the use of extensions when the user has
406  asked for TLS 1.1+ support */
407  status = openPacketStreamSSL( stream, sessionInfoPtr, CRYPT_USE_DEFAULT,
409  if( cryptStatusError( status ) )
410  return( status );
411  status = continueHSPacketStream( stream, SSL_HAND_CLIENT_HELLO,
412  &packetOffset );
413  if( cryptStatusError( status ) )
414  {
415  sMemDisconnect( stream );
416  return( status );
417  }
418  sputc( stream, SSL_MAJOR_VERSION );
419  sputc( stream, sessionInfoPtr->version );
420  handshakeInfo->clientOfferedVersion = sessionInfoPtr->version;
421  swrite( stream, handshakeInfo->clientNonce, SSL_NONCE_SIZE );
422  sputc( stream, handshakeInfo->sessionIDlength );
423  if( handshakeInfo->sessionIDlength > 0 )
424  {
425  swrite( stream, handshakeInfo->sessionID,
426  handshakeInfo->sessionIDlength );
427  sessionIDsent = TRUE;
428  }
429  status = writeCipherSuiteList( stream,
430  findSessionInfo( sessionInfoPtr->attributeList,
431  CRYPT_SESSINFO_USERNAME ) != NULL ? \
432  TRUE : FALSE,
433  ( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS12 ) ? \
434  TRUE : FALSE,
435  isServer( sessionInfoPtr ),
436  sessionInfoPtr->protocolFlags & SSL_PFLAG_SUITEB );
437  if( cryptStatusOK( status ) )
438  {
439  sputc( stream, 1 ); /* No compression */
440  status = sputc( stream, 0 );
441  }
442  if( cryptStatusOK( status ) && \
443  sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS11 )
444  {
445  /* Extensions are only written when newer versions of TLS are
446  enabled, see the comment earlier for details */
447  status = writeClientExtensions( stream, sessionInfoPtr );
448  }
449  if( cryptStatusOK( status ) )
450  status = completeHSPacketStream( stream, packetOffset );
451  if( cryptStatusOK( status ) )
452  status = sendPacketSSL( sessionInfoPtr, stream, FALSE );
453  if( cryptStatusError( status ) )
454  {
455  sMemDisconnect( stream );
456  return( status );
457  }
458 
459  /* Perform the assorted hashing of the client hello in between the
460  network ops where it's effectively free */
461  status = hashHSPacketWrite( handshakeInfo, stream, 0 );
462  sMemDisconnect( stream );
463  if( cryptStatusError( status ) )
464  return( status );
465 
466  /* Process the server hello. The server usually sends us a session ID
467  to indicate a (potentially) resumable session, indicated by a return
468  status of OK_SPECIAL, but we don't do anything further with it since
469  we won't be resuming the session.
470 
471  Note that this processing leads to a slight inefficiency in hashing
472  when multiple hash algorithms need to be accomodated (as they do
473  when TLS 1.2+ is enabled) because readHSPacketSSL() hashes the
474  incoming packet data as it arrives, and if all possible server
475  handshake packets are combined into a single SSL message packet then
476  they'll arrive, and need to be hashed, before the server hello is
477  processed and we can selectively disable the hash algorithms that
478  won't be needed. Fixing this would require adding special-case
479  processing to readHSPacketSSL() to detect the use of
480  SSL_MSG_FIRST_HANDSHAKE for the client and skip the hashing, relying
481  on the calling code to then pick out the portions that need to be
482  hashed. This probably isn't worth the effort required, since it adds
483  a lot of code complexity and custom processing just to save a small
484  amount of hashing on the client, which will generally be the less
485  resource-constrained of the two parties */
486  status = readHSPacketSSL( sessionInfoPtr, handshakeInfo, &length,
488  if( cryptStatusError( status ) )
489  return( status );
490  sMemConnect( stream, sessionInfoPtr->receiveBuffer, length );
491  status = processHelloSSL( sessionInfoPtr, handshakeInfo, stream, FALSE );
492  if( cryptStatusError( status ) )
493  {
494  int resumedSessionID;
495 
496  if( status != OK_SPECIAL )
497  {
498  sMemDisconnect( stream );
499  return( status );
500  }
501 
502  /* The server has sent us a sessionID in an attempt to resume a
503  previous session, see if it's in the session cache. If it's
504  present then the server hello is followed immediately by the
505  change cipherspec, which is sent by the shared handshake
506  completion code */
507  resumedSessionID = \
508  lookupScoreboardEntry( sessionInfoPtr->sessionSSL->scoreboardInfoPtr,
509  SCOREBOARD_KEY_SESSIONID_CLI, handshakeInfo->sessionID,
510  handshakeInfo->sessionIDlength,
511  &lookupResult );
512 #ifdef CONFIG_SUITEB_TESTS
513  resumedSessionID = CRYPT_ERROR; /* Disable for Suite B tests */
514 #endif /* CONFIG_SUITEB_TESTS */
515  if( !cryptStatusError( resumedSessionID ) )
516  {
517  sMemDisconnect( stream );
518 
519  /* Make sure that the session that the server OK'd for resumption
520  was the one that we actually asked for */
521  if( !sessionIDsent || \
522  ( handshakeInfo->sessionIDlength != sentSessionIDlength || \
523  memcmp( handshakeInfo->sessionID, sentSessionID,
524  sentSessionIDlength ) ) )
525  {
526  /* Something very odd is going on, the server has told us to
527  resume a session that we didn't ask for or don't know
528  about */
531  "Server indicated that a non-valid session should "
532  "be resumed" ) );
533  }
534 
535  /* We're resuming a previous session, remember the premaster
536  secret */
537  status = attributeCopyParams( handshakeInfo->premasterSecret,
539  &handshakeInfo->premasterSecretSize,
540  lookupResult.data,
541  lookupResult.dataSize );
542  ENSURES( cryptStatusOK( status ) );
543 
544  /* Tell the caller that it's a resumed session */
545  DEBUG_PRINT(( "Resuming session with server based on "
546  "sessionID = \n" ));
547  DEBUG_DUMP_DATA( handshakeInfo->sessionID,
548  handshakeInfo->sessionIDlength );
549  return( OK_SPECIAL );
550  }
551  }
552 
553  return( CRYPT_OK );
554  }
555 
556 /* Exchange keys with the server */
557 
558 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
559 static int exchangeClientKeys( INOUT SESSION_INFO *sessionInfoPtr,
560  INOUT SSL_HANDSHAKE_INFO *handshakeInfo )
561  {
562  STREAM *stream = &handshakeInfo->stream;
563  BYTE keyexPublicValue[ CRYPT_MAX_PKCSIZE + 8 ];
564  BOOLEAN needClientCert = FALSE;
565  int packetOffset, packetStreamOffset = 0, length;
566  int keyexPublicValueLen = DUMMY_INIT, status;
567 
568  assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
569  assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
570 
571  /* Process the optional server supplemental data:
572 
573  byte ID = SSL_HAND_SUPPLEMENTAL_DATA
574  uint24 len
575  uint16 type
576  uint16 len
577  byte[] value
578 
579  This is a kitchen-sink mechanism for exchanging arbitrary further
580  data during the TLS handshake (see RFC 4680). The presence of the
581  supplemental data has to be negotiated using TLS extensions, however
582  the nature of this negotiation is unspecified so we can't just
583  reject an unexpected supplemental data message as required by the RFC
584  because it may have been quite legitimately negotiated by a TLS
585  extension that we don't know about. Because of this we perform
586  basic validity checks on any supplemental data messages that arrive
587  but otherwise ignore them */
588  status = refreshHSStream( sessionInfoPtr, handshakeInfo );
589  if( cryptStatusError( status ) )
590  return( status );
591  if( sPeek( stream ) == SSL_HAND_SUPPLEMENTAL_DATA )
592  {
593  status = checkHSPacketHeader( sessionInfoPtr, stream, &length,
595  UINT16_SIZE + UINT16_SIZE + 1 );
596  if( cryptStatusError( status ) )
597  {
598  sMemDisconnect( stream );
599  return( status );
600  }
601  readUint16( stream ); /* Type */
602  status = readUniversal16( stream ); /* Value */
603  if( cryptStatusError( status ) )
604  {
605  sMemDisconnect( stream );
608  "Invalid supplemental data" ) );
609  }
610  }
611 
612  /* Process the optional server certificate chain:
613 
614  byte ID = SSL_HAND_CERTIFICATE
615  uint24 len
616  uint24 certLen -- 1...n certificates ordered
617  byte[] certificate -- leaf -> root */
618  if( handshakeInfo->authAlgo != CRYPT_ALGO_NONE )
619  {
620  status = refreshHSStream( sessionInfoPtr, handshakeInfo );
621  if( cryptStatusError( status ) )
622  return( status );
623  status = readSSLCertChain( sessionInfoPtr, handshakeInfo,
624  stream, &sessionInfoPtr->iKeyexCryptContext,
625  FALSE );
626  if( cryptStatusError( status ) )
627  {
628  sMemDisconnect( stream );
629  return( status );
630  }
631  }
632 
633  /* Process the optional server keyex:
634 
635  byte ID = SSL_HAND_SERVER_KEYEXCHANGE
636  uint24 len
637  DH:
638  uint16 dh_pLen
639  byte[] dh_p
640  uint16 dh_gLen
641  byte[] dh_g
642  uint16 dh_YsLen
643  byte[] dh_Ys
644  [ byte hashAlgoID -- TLS 1.2 ]
645  [ byte sigAlgoID -- TLS 1.2 ]
646  uint16 signatureLen
647  byte[] signature
648  ECDH:
649  byte curveType
650  uint16 namedCurve
651  uint8 ecPointLen -- NB uint8 not uint16
652  byte[] ecPoint
653  [ byte hashAlgoID -- TLS 1.2 ]
654  [ byte sigAlgoID -- TLS 1.2 ]
655  uint16 signatureLen
656  byte[] signature */
657  if( isKeyxAlgo( handshakeInfo->keyexAlgo ) )
658  {
659  KEYAGREE_PARAMS keyAgreeParams, tempKeyAgreeParams;
660  void *keyData = DUMMY_INIT_PTR;
661  const BOOLEAN isECC = isEccAlgo( handshakeInfo->keyexAlgo );
662  int keyDataOffset, keyDataLength = DUMMY_INIT;
663 
664  status = refreshHSStream( sessionInfoPtr, handshakeInfo );
665  if( cryptStatusError( status ) )
666  return( status );
667 
668  /* Make sure that we've got an appropriate server keyex packet. We
669  set the minimum key size to MIN_PKCSIZE_THRESHOLD/
670  MIN_PKCSIZE_ECC_THRESHOLD instead of MIN_PKCSIZE/MIN_PKCSIZE_ECC
671  in order to provide better diagnostics if the server is using
672  weak keys since otherwise the data will be rejected in the packet
673  read long before we get to the keysize check */
674  status = checkHSPacketHeader( sessionInfoPtr, stream, &length,
676  isECC ? \
677  ( 1 + UINT16_SIZE + \
681  UINT16_SIZE + 1 + \
684  if( cryptStatusError( status ) )
685  {
686  sMemDisconnect( stream );
687  return( status );
688  }
689 
690  /* Process the server keyex and convert it into a DH/ECDH context */
691  keyDataOffset = stell( stream );
692  status = processServerKeyex( stream, &keyAgreeParams,
693  &handshakeInfo->dhContext, isECC );
694  if( cryptStatusOK( status ) )
695  {
696  keyDataLength = stell( stream ) - keyDataOffset;
697  status = sMemGetDataBlockAbs( stream, keyDataOffset, &keyData,
698  keyDataLength );
699  }
700  if( cryptStatusError( status ) )
701  {
702  sMemDisconnect( stream );
703 
704  /* Some misconfigured servers may use very short keys, we
705  perform a special-case check for these and return a more
706  specific message than the generic bad-data error */
707  if( status == CRYPT_ERROR_NOSECURE )
708  {
711  "Insecure key used in key exchange" ) );
712  }
713 
714  retExt( cryptArgError( status ) ? \
715  CRYPT_ERROR_BADDATA : status,
716  ( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status,
718  "Invalid server key agreement parameters" ) );
719  }
720  ANALYSER_HINT( keyData != NULL );
721 
722  /* Check the server's signature on the DH/ECDH parameters */
723  status = checkKeyexSignature( sessionInfoPtr, handshakeInfo,
724  stream, keyData, keyDataLength,
725  isECC );
726  if( cryptStatusError( status ) )
727  {
728  sMemDisconnect( stream );
729  retExt( status,
730  ( status, SESSION_ERRINFO,
731  "Invalid server key agreement parameter signature" ) );
732  }
733 
734  /* Perform phase 1 of the DH/ECDH key agreement process and save the
735  result so that we can send it to the server later on. The order
736  of the SSL messages is a bit unfortunate since we get the one for
737  phase 2 before we need the phase 1 value, so we have to cache the
738  phase 1 result for when we need it later on */
739  memset( &tempKeyAgreeParams, 0, sizeof( KEYAGREE_PARAMS ) );
740  status = krnlSendMessage( handshakeInfo->dhContext,
741  IMESSAGE_CTX_ENCRYPT, &tempKeyAgreeParams,
742  sizeof( KEYAGREE_PARAMS ) );
743  if( cryptStatusError( status ) )
744  {
745  zeroise( &tempKeyAgreeParams, sizeof( KEYAGREE_PARAMS ) );
746  sMemDisconnect( stream );
747  return( status );
748  }
749  ENSURES( rangeCheckZ( 0, tempKeyAgreeParams.publicValueLen,
750  CRYPT_MAX_PKCSIZE ) );
751  memcpy( keyexPublicValue, tempKeyAgreeParams.publicValue,
752  tempKeyAgreeParams.publicValueLen );
753  keyexPublicValueLen = tempKeyAgreeParams.publicValueLen;
754  zeroise( &tempKeyAgreeParams, sizeof( KEYAGREE_PARAMS ) );
755 
756  /* Perform phase 2 of the DH/ECDH key agreement */
757  status = krnlSendMessage( handshakeInfo->dhContext,
758  IMESSAGE_CTX_DECRYPT, &keyAgreeParams,
759  sizeof( KEYAGREE_PARAMS ) );
760  if( cryptStatusError( status ) )
761  {
762  zeroise( &keyAgreeParams, sizeof( KEYAGREE_PARAMS ) );
763  sMemDisconnect( stream );
764  return( status );
765  }
766  if( isECC )
767  {
768  const int xCoordLen = ( keyAgreeParams.wrappedKeyLen - 1 ) / 2;
769 
770  /* The output of the ECDH operation is an ECC point, but for
771  some unknown reason TLS only uses the x coordinate and not
772  the full point. To work around this we have to rewrite the
773  point as a standalone x coordinate, which is relatively
774  easy because we're using an "uncompressed" point format:
775 
776  +---+---------------+---------------+
777  |04 | qx | qy |
778  +---+---------------+---------------+
779  |<- fldSize --> |<- fldSize --> | */
780  REQUIRES( keyAgreeParams.wrappedKeyLen >= MIN_PKCSIZE_ECCPOINT && \
781  keyAgreeParams.wrappedKeyLen <= MAX_PKCSIZE_ECCPOINT && \
782  ( keyAgreeParams.wrappedKeyLen & 1 ) == 1 && \
783  keyAgreeParams.wrappedKey[ 0 ] == 0x04 );
784  memmove( keyAgreeParams.wrappedKey,
785  keyAgreeParams.wrappedKey + 1, xCoordLen );
786  keyAgreeParams.wrappedKeyLen = xCoordLen;
787  }
788  ENSURES( rangeCheckZ( 0, keyAgreeParams.wrappedKeyLen,
790  memcpy( handshakeInfo->premasterSecret, keyAgreeParams.wrappedKey,
791  keyAgreeParams.wrappedKeyLen );
792  handshakeInfo->premasterSecretSize = keyAgreeParams.wrappedKeyLen;
793  zeroise( &keyAgreeParams, sizeof( KEYAGREE_PARAMS ) );
794  }
795 
796  /* Process the optional server certificate request:
797 
798  byte ID = SSL_HAND_SERVER_CERTREQUEST
799  uint24 len
800  byte certTypeLen
801  byte[] certType
802  [ uint16 sigHashListLen -- TLS 1.2 ]
803  [ byte hashAlgoID -- TLS 1.2 ]
804  [ byte sigAlgoID -- TLS 1.2 ]
805  uint16 caNameListLen
806  uint16 caNameLen
807  byte[] caName
808 
809  We don't really care what's in the certificate request packet since
810  the contents are irrelevant, in a number of cases servers have been
811  known to send out superfluous certificate requests without the admins
812  even knowing that they're doing it, in other cases servers send out
813  requests for every CA that they know of (150-160 CAs), which is
814  pretty much meaningless since they can't possibly trust all of those
815  CAs to authorise access to their site. Because of this, all that we
816  do here is perform a basic sanity check and remember that we may need
817  to submit a certificate later on.
818 
819  See the long comment in the cert-request handling code in ssl_svr.c
820  for the handling of the sigHashList.
821 
822  Since we're about to peek ahead into the stream to see if we need to
823  process a server certificate request, we have to refresh the stream
824  at this point in case the certificate request wasn't bundled with the
825  preceding packets */
826  status = refreshHSStream( sessionInfoPtr, handshakeInfo );
827  if( cryptStatusError( status ) )
828  return( status );
829  if( sPeek( stream ) == SSL_HAND_SERVER_CERTREQUEST )
830  {
831  /* Although the spec says that at least one CA name entry must be
832  present, some implementations send a zero-length list so we allow
833  this as well. The spec was changed in late TLS 1.1 drafts to
834  reflect this practice */
835  status = checkHSPacketHeader( sessionInfoPtr, stream, &length,
837  1 + 1 + \
838  ( ( sessionInfoPtr->version >= \
840  ( UINT16_SIZE + 1 + 1 ) : 0 ) + \
841  UINT16_SIZE );
842  if( cryptStatusError( status ) )
843  {
844  sMemDisconnect( stream );
845  return( status );
846  }
847  status = length = sgetc( stream );
848  if( !cryptStatusError( status ) )
849  {
850  if( length < 1 || length > 64 )
851  status = CRYPT_ERROR_BADDATA;
852  }
853  if( !cryptStatusError( status ) )
854  status = sSkip( stream, length );
855  if( cryptStatusError( status ) )
856  {
857  sMemDisconnect( stream );
860  "Invalid certificate request certificate-type "
861  "information" ) );
862  }
863  if( sessionInfoPtr->version >= SSL_MINOR_VERSION_TLS12 )
864  {
865  status = length = readUint16( stream );
866  if( !cryptStatusError( status ) )
867  {
868  if( length < UINT16_SIZE || length > 64 || \
869  ( length % UINT16_SIZE ) != 0 )
870  status = CRYPT_ERROR_BADDATA;
871  }
872  if( !cryptStatusError( status ) )
873  status = sSkip( stream, length );
874  if( cryptStatusError( status ) )
875  {
876  sMemDisconnect( stream );
879  "Invalid certificate request signature/hash "
880  "algorithm information" ) );
881  }
882  }
883  status = readUniversal16( stream );
884  if( cryptStatusError( status ) )
885  {
886  sMemDisconnect( stream );
889  "Invalid certificate request CA name list" ) );
890  }
891  needClientCert = TRUE;
892  }
893 
894  /* Process the server hello done:
895 
896  byte ID = SSL_HAND_SERVER_HELLODONE
897  uint24 len = 0 */
898  status = refreshHSStream( sessionInfoPtr, handshakeInfo );
899  if( cryptStatusError( status ) )
900  return( status );
901  status = checkHSPacketHeader( sessionInfoPtr, stream, &length,
903  if( cryptStatusError( status ) )
904  {
905  sMemDisconnect( stream );
906  return( status );
907  }
908 
909  /* If we need a client certificate, build the client certificate packet */
910  status = openPacketStreamSSL( stream, sessionInfoPtr, CRYPT_USE_DEFAULT,
912  if( cryptStatusError( status ) )
913  return( status );
914  if( needClientCert )
915  {
916  BOOLEAN sentResponse = FALSE;
917 
918  /* If we haven't got a certificate available, tell the server. SSL
919  and TLS differ here, SSL sends a no-certificate alert while TLS
920  sends an empty client certificate packet, which is handled
921  further on */
922  if( sessionInfoPtr->privateKey == CRYPT_ERROR )
923  {
924  setErrorInfo( sessionInfoPtr, CRYPT_SESSINFO_PRIVATEKEY,
926  if( sessionInfoPtr->version == SSL_MINOR_VERSION_SSL )
927  {
928  static const BYTE FAR_BSS noCertAlertSSLTemplate[] = {
929  SSL_MSG_ALERT, /* ID */
931  0, 2, /* Length */
933  };
934 
935  /* This is an alert-protocol message rather than a handshake
936  message so we don't add it to the handshake packet stream
937  but write it directly to the network stream */
938  swrite( &sessionInfoPtr->stream, noCertAlertSSLTemplate, 7 );
939  sentResponse = TRUE;
940  }
941 
942  /* The reaction to the lack of a certificate is up to the server
943  (some just request one anyway even though they can't do
944  anything with it) so from here on we just continue as if
945  nothing had happened */
946  sessionInfoPtr->protocolFlags |= SSL_PFLAG_CLIAUTHSKIPPED;
947  needClientCert = FALSE;
948  }
949 
950  /* If we haven't sent a response yet, send it now. If no private
951  key is available this will send the zero-length chain that's
952  required by TLS */
953  if( !sentResponse )
954  {
955  status = writeSSLCertChain( sessionInfoPtr, stream );
956  if( cryptStatusError( status ) )
957  {
958  sMemDisconnect( stream );
959  return( status );
960  }
961  }
962  }
963 
964  /* Build the client key exchange packet:
965 
966  byte ID = SSL_HAND_CLIENT_KEYEXCHANGE
967  uint24 len
968  DH:
969  uint16 yLen
970  byte[] y
971  ECDH:
972  uint8 ecPointLen -- NB uint8 not uint16
973  byte[] ecPoint
974  PSK:
975  uint16 userIDLen
976  byte[] userID
977  RSA:
978  [ uint16 encKeyLen -- TLS only ]
979  byte[] rsaPKCS1( byte[2] { 0x03, 0x0n } || byte[46] random ) */
980  status = continueHSPacketStream( stream, SSL_HAND_CLIENT_KEYEXCHANGE,
981  &packetOffset );
982  if( cryptStatusError( status ) )
983  {
984  sMemDisconnect( stream );
985  return( status );
986  }
987  if( isKeyxAlgo( handshakeInfo->keyexAlgo ) )
988  {
989  /* Write the DH/ECDH public value that we saved earlier when we
990  performed phase 1 of the key agreement process */
991  if( isEccAlgo( handshakeInfo->keyexAlgo ) )
992  {
993  sputc( stream, keyexPublicValueLen );
994  status = swrite( stream, keyexPublicValue,
995  keyexPublicValueLen );
996  }
997  else
998  {
999  status = writeInteger16U( stream, keyexPublicValue,
1000  keyexPublicValueLen );
1001  }
1002  }
1003  else
1004  {
1005  if( handshakeInfo->authAlgo == CRYPT_ALGO_NONE )
1006  {
1007  const ATTRIBUTE_LIST *passwordPtr = \
1008  findSessionInfo( sessionInfoPtr->attributeList,
1010  const ATTRIBUTE_LIST *userNamePtr = \
1011  findSessionInfo( sessionInfoPtr->attributeList,
1013 
1014  REQUIRES( passwordPtr != NULL );
1015  REQUIRES( userNamePtr != NULL );
1016 
1017  /* Create the shared premaster secret from the user password */
1018  status = createSharedPremasterSecret( \
1019  handshakeInfo->premasterSecret,
1021  &handshakeInfo->premasterSecretSize,
1022  passwordPtr->value,
1023  passwordPtr->valueLength,
1024  ( passwordPtr->flags & ATTR_FLAG_ENCODEDVALUE ) ? \
1025  TRUE : FALSE );
1026  if( cryptStatusError( status ) )
1027  {
1028  sMemDisconnect( stream );
1029  retExt( status,
1030  ( status, SESSION_ERRINFO,
1031  "Couldn't create master secret from shared "
1032  "secret/password value" ) );
1033  }
1034 
1035  /* Write the PSK client identity */
1036  writeUint16( stream, userNamePtr->valueLength );
1037  status = swrite( stream, userNamePtr->value,
1038  userNamePtr->valueLength );
1039  }
1040  else
1041  {
1042  BYTE wrappedKey[ CRYPT_MAX_PKCSIZE + 8 ];
1043  int wrappedKeyLength;
1044 
1045  status = wrapPremasterSecret( sessionInfoPtr, handshakeInfo,
1046  wrappedKey, CRYPT_MAX_PKCSIZE,
1047  &wrappedKeyLength );
1048  if( cryptStatusError( status ) )
1049  {
1050  sMemDisconnect( stream );
1051  return( status );
1052  }
1053  if( sessionInfoPtr->version <= SSL_MINOR_VERSION_SSL )
1054  {
1055  /* The original Netscape SSL implementation didn't provide a
1056  length for the encrypted key and everyone copied that so
1057  it became the de facto standard way to do it (sic faciunt
1058  omnes. The spec itself is ambiguous on the topic). This
1059  was fixed in TLS (although the spec is still ambiguous) so
1060  the encoding differs slightly between SSL and TLS */
1061  status = swrite( stream, wrappedKey, wrappedKeyLength );
1062  }
1063  else
1064  {
1065  status = writeInteger16U( stream, wrappedKey,
1066  wrappedKeyLength );
1067  }
1068  }
1069  }
1070  if( cryptStatusOK( status ) )
1071  status = completeHSPacketStream( stream, packetOffset );
1072  if( cryptStatusError( status ) )
1073  {
1074  sMemDisconnect( stream );
1075  return( status );
1076  }
1077 
1078  /* If we need to supply a client certificate, send the signature
1079  generated with the certificate to prove possession of the private
1080  key */
1081  if( needClientCert )
1082  {
1083  /* Since the client certificate-verify message requires the hash of
1084  all handshake packets up to this point, we have to interrupt the
1085  processing to hash them before we continue */
1086  status = completePacketStreamSSL( stream, 0 );
1087  if( cryptStatusOK( status ) )
1088  status = hashHSPacketWrite( handshakeInfo, stream, 0 );
1089  if( cryptStatusOK( status ) )
1090  status = createCertVerifyHash( sessionInfoPtr, handshakeInfo );
1091  if( cryptStatusError( status ) )
1092  {
1093  sMemDisconnect( stream );
1094  return( status );
1095  }
1096 
1097  /* Write the packet header and drop in the signature data. Since
1098  we've interrupted the packet stream to perform the hashing we
1099  have to restart it at this point */
1100  status = continuePacketStreamSSL( stream, sessionInfoPtr,
1102  &packetStreamOffset );
1103  if( cryptStatusError( status ) )
1104  return( status );
1105  status = continueHSPacketStream( stream, SSL_HAND_CLIENT_CERTVERIFY,
1106  &packetOffset );
1107  if( cryptStatusOK( status ) )
1108  status = createCertVerify( sessionInfoPtr, handshakeInfo,
1109  stream );
1110  if( cryptStatusOK( status ) )
1111  status = completeHSPacketStream( stream, packetOffset );
1112  if( cryptStatusError( status ) )
1113  {
1114  sMemDisconnect( stream );
1115  return( status );
1116  }
1117  }
1118 
1119  /* Wrap the packet and perform the assorted hashing for it. This is
1120  followed by the change cipherspec packet so we don't send it at this
1121  point but leave it to be sent by the shared handshake-completion
1122  code */
1123  status = completePacketStreamSSL( stream, packetStreamOffset );
1124  if( cryptStatusOK( status ) )
1125  status = hashHSPacketWrite( handshakeInfo, stream,
1126  packetStreamOffset );
1127  return( status );
1128  }
1129 
1130 /****************************************************************************
1131 * *
1132 * Session Access Routines *
1133 * *
1134 ****************************************************************************/
1135 
1136 STDC_NONNULL_ARG( ( 1 ) ) \
1137 void initSSLclientProcessing( INOUT SSL_HANDSHAKE_INFO *handshakeInfo )
1138  {
1139  assert( isWritePtr( handshakeInfo, sizeof( SSL_HANDSHAKE_INFO ) ) );
1140 
1141  handshakeInfo->beginHandshake = beginClientHandshake;
1142  handshakeInfo->exchangeKeys = exchangeClientKeys;
1143  }
1144 #endif /* USE_SSL */