cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
key_rd.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * Public/Private Key Read Routines *
4 * Copyright Peter Gutmann 1992-2009 *
5 * *
6 ****************************************************************************/
7 
8 #include <stdio.h>
9 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
10 #if defined( INC_ALL )
11  #include "context.h"
12  #include "asn1.h"
13  #include "asn1_ext.h"
14  #include "misc_rw.h"
15  #include "pgp.h"
16 #else
17  #include "context/context.h"
18  #include "enc_dec/asn1.h"
19  #include "enc_dec/asn1_ext.h"
20  #include "enc_dec/misc_rw.h"
21  #include "misc/pgp.h"
22 #endif /* Compiler-specific includes */
23 
24 /* Although there is a fair amount of commonality between public and private-
25  key functions, we keep them distinct to enforce red/black separation.
26 
27  The DLP algorithms split the key components over the information in the
28  AlgorithmIdentifier and the actual public/private key components, with the
29  (p, q, g) set classed as domain parameters and included in the
30  AlgorithmIdentifier and y being the actual key.
31 
32  params = SEQ {
33  p INTEGER,
34  q INTEGER, -- q for DSA
35  g INTEGER, -- g for DSA
36  j INTEGER OPTIONAL, -- X9.42 only
37  validationParams [...] -- X9.42 only
38  }
39 
40  key = y INTEGER -- g^x mod p
41 
42  For peculiar historical reasons (copying errors and the use of obsolete
43  drafts as reference material) the X9.42 interpretation used in PKIX
44  reverses the second two parameters from FIPS 186 (so it uses p, g, q
45  instead of p, q, g), so when we read/write the parameter information we
46  have to switch the order in which we read the values if the algorithm
47  isn't DSA */
48 
49 #define hasReversedParams( cryptAlgo ) \
50  ( ( cryptAlgo ) == CRYPT_ALGO_DH || \
51  ( cryptAlgo ) == CRYPT_ALGO_ELGAMAL )
52 
53 #ifdef USE_PKC
54 
55 /****************************************************************************
56 * *
57 * Read Public Keys *
58 * *
59 ****************************************************************************/
60 
61 /* Read X.509 SubjectPublicKeyInfo public keys */
62 
63 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
64 static int readRsaSubjectPublicKey( INOUT STREAM *stream,
66  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
67  {
69  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
70  int status;
71 
72  assert( isWritePtr( stream, sizeof( STREAM ) ) );
73  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
74  assert( isWritePtr( actionFlags, sizeof( int ) ) );
75 
76  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
77  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
78 
79  /* Clear return value */
80  *actionFlags = ACTION_PERM_NONE;
81 
82  /* Read the SubjectPublicKeyInfo header field and parameter data if
83  there's any present. We read the outer wrapper in generic form since
84  it may be context-specific-tagged if it's coming from a keyset (RSA
85  public keys is the one place where PKCS #15 keys differ from X.509
86  ones) or something odd from CRMF */
87  readGenericHole( stream, NULL, 8 + MIN_PKCSIZE_THRESHOLD + RSAPARAM_MIN_E,
88  DEFAULT_TAG );
89  status = readAlgoID( stream, &cryptAlgo, ALGOID_CLASS_PKC );
90  if( cryptStatusError( status ) )
91  return( status );
92  if( cryptAlgo != CRYPT_ALGO_RSA )
93  return( CRYPT_ERROR_BADDATA );
94 
95  /* Set the maximum permitted actions. More restrictive permissions may
96  be set by higher-level code if required and in particular if the key
97  is a pure public key rather than merely the public portions of a
98  private key the actions will be restricted at that point to encrypt
99  and signature-check only */
100  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
101  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL ) | \
102  MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL ) | \
103  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL );
104 
105  /* Read the BIT STRING encapsulation and the public key fields */
106  readBitStringHole( stream, NULL, MIN_PKCSIZE_THRESHOLD, DEFAULT_TAG );
107  readSequence( stream, NULL );
108  status = readBignumChecked( stream, &rsaKey->rsaParam_n,
110  if( cryptStatusOK( status ) )
111  status = readBignum( stream, &rsaKey->rsaParam_e,
113  &rsaKey->rsaParam_n );
114  return( status );
115  }
116 
117 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
118 static int readDlpSubjectPublicKey( INOUT STREAM *stream,
119  INOUT CONTEXT_INFO *contextInfoPtr,
120  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
121  {
122  PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
124  int extraLength, status;
125 
126  assert( isWritePtr( stream, sizeof( STREAM ) ) );
127  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
128  assert( isWritePtr( actionFlags, sizeof( int ) ) );
129 
130  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
131  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
132  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
133  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
134 
135  /* Clear return value */
136  *actionFlags = ACTION_PERM_NONE;
137 
138  /* Read the SubjectPublicKeyInfo header field and make sure that the DLP
139  parameter data is present */
140  readGenericHole( stream, NULL,
143  status = readAlgoIDparam( stream, &cryptAlgo, &extraLength,
145  if( cryptStatusError( status ) )
146  return( status );
147  if( extraLength <= 0 )
148  return( CRYPT_ERROR_BADDATA );
149  if( contextInfoPtr->capabilityInfo->cryptAlgo != cryptAlgo )
150  return( CRYPT_ERROR_BADDATA );
151 
152  /* Read the header and key parameters */
153  readSequence( stream, NULL );
154  status = readBignumChecked( stream, &dlpKey->dlpParam_p,
156  if( cryptStatusError( status ) )
157  return( status );
158  if( hasReversedParams( cryptAlgo ) )
159  {
160  status = readBignum( stream, &dlpKey->dlpParam_g, DLPPARAM_MIN_G,
161  DLPPARAM_MAX_G, &dlpKey->dlpParam_p );
162  if( cryptStatusOK( status ) )
163  status = readBignum( stream, &dlpKey->dlpParam_q, DLPPARAM_MIN_Q,
164  DLPPARAM_MAX_Q, &dlpKey->dlpParam_p );
165  }
166  else
167  {
168  status = readBignum( stream, &dlpKey->dlpParam_q, DLPPARAM_MIN_Q,
169  DLPPARAM_MAX_Q, &dlpKey->dlpParam_p );
170  if( cryptStatusOK( status ) )
171  status = readBignum( stream, &dlpKey->dlpParam_g, DLPPARAM_MIN_G,
172  DLPPARAM_MAX_G, &dlpKey->dlpParam_p );
173  }
174  if( cryptStatusError( status ) )
175  return( status );
176 
177  /* Set the maximum permitted actions. Because of the special-case data
178  formatting requirements for DLP algorithms we make the usage
179  internal-only. If the key is a pure public key rather than merely
180  the public portions of a private key the actions will be restricted
181  by higher-level code to signature-check only */
182  if( cryptAlgo == CRYPT_ALGO_DSA )
183  {
184  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
186  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
188  }
189  else
190  {
191  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
193  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
195  }
196 
197  /* Read the BIT STRING encapsulation and the public key fields */
198  readBitStringHole( stream, NULL, MIN_PKCSIZE_THRESHOLD, DEFAULT_TAG );
199  return( readBignumChecked( stream, &dlpKey->dlpParam_y,
201  &dlpKey->dlpParam_p ) );
202  }
203 
204 #if defined( USE_ECDH ) || defined( USE_ECDSA )
205 
206 static const OID_INFO FAR_BSS eccOIDinfo[] = {
207  /* NIST P-192, X9.62 p192r1, SECG p192r1, 1 2 840 10045 3 1 1 */
208  { MKOID( "\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x01" ), CRYPT_ECCCURVE_P192 },
209  /* NIST P-224, X9.62 P224r1, SECG p224r1, 1 3 132 0 33 */
210  { MKOID( "\x06\x05\x2B\x81\x04\x00\x21" ), CRYPT_ECCCURVE_P224 },
211  /* NIST P-256, X9.62 p256r1, SECG p256r1, 1 2 840 10045 3 1 7 */
212  { MKOID( "\x06\x08\x2A\x86\x48\xCE\x3D\x03\x01\x07" ), CRYPT_ECCCURVE_P256 },
213  /* NIST P-384, SECG p384r1, 1 3 132 0 34 */
214  { MKOID( "\x06\x05\x2B\x81\x04\x00\x22" ), CRYPT_ECCCURVE_P384 },
215  /* NIST P-521, SECG p521r1, 1 3 132 0 35 */
216  { MKOID( "\x06\x05\x2B\x81\x04\x00\x23" ), CRYPT_ECCCURVE_P521 },
217  { NULL, 0 }, { NULL, 0 }
218  };
219 
220 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
221 int getECCOidTbl( OUT const OID_INFO **oidTblPtr,
222  OUT_INT_Z int *noOidTblEntries )
223  {
224  assert( isReadPtr( oidTblPtr, sizeof( OID_INFO * ) ) );
225  assert( isWritePtr( noOidTblEntries, sizeof( int ) ) );
226 
227  *oidTblPtr = eccOIDinfo;
228  *noOidTblEntries = FAILSAFE_ARRAYSIZE( eccOIDinfo, OID_INFO );
229 
230  return( CRYPT_OK );
231  }
232 
233 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
234 static int readEccSubjectPublicKey( INOUT STREAM *stream,
235  INOUT CONTEXT_INFO *contextInfoPtr,
236  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
237  {
238  PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
241  const OID_INFO *oidTbl;
242  int oidTblSize, fieldSize = DUMMY_INIT, selectionID = DUMMY_INIT;
243  int length, status;
244 
245  assert( isWritePtr( stream, sizeof( STREAM ) ) );
246  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
247  assert( isWritePtr( actionFlags, sizeof( int ) ) );
248 
249  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
250  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
251 
252  /* Clear return value */
253  *actionFlags = ACTION_PERM_NONE;
254 
255  /* Read the SubjectPublicKeyInfo header field and make sure that the ECC
256  parameter data is present. Because of the more or less arbitrary
257  manner in which these parameters can be represented we have to be
258  fairly open-ended in terms of the data size limits that we use, and
259  in particular for named curves the lower bound is the size of a
260  single OID that defines the curve */
261  readGenericHole( stream, NULL,
263  DEFAULT_TAG );
264  status = readAlgoIDparam( stream, &cryptAlgo, &length,
266  if( cryptStatusError( status ) )
267  return( status );
268  if( length < MIN_OID_SIZE || \
269  contextInfoPtr->capabilityInfo->cryptAlgo != cryptAlgo )
270  return( CRYPT_ERROR_BADDATA );
271 
272  /* Now things get messy, since the ECC standards authors carefully
273  sidestepped having to make a decision about anything and instead
274  just created an open framework into which it's possible to drop
275  almost anything. To keep things sane we require the use of named
276  curves (which most people seem to use) over a prime field */
277  status = getECCOidTbl( &oidTbl, &oidTblSize );
278  if( cryptStatusOK( status ) )
279  status = readOID( stream, oidTbl, oidTblSize, &selectionID );
280  if( cryptStatusOK( status ) )
281  status = getECCFieldSize( selectionID, &fieldSize );
282  if( cryptStatusError( status ) )
283  return( status );
284  eccKey->curveType = selectionID;
285 
286  /* Set the maximum permitted actions. Because of the special-case data
287  formatting requirements for ECC algorithms (which are a part of the
288  DLP algorithm family) we make the usage internal-only. If the key is
289  a pure public key rather than merely the public portions of a private
290  key the actions will be restricted by higher-level code to signature-
291  check only */
292  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
294  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
296 
297  /* Read the BIT STRING encapsulation and the public key fields. Instead
298  of encoding the necessary information as an obvious OID + SEQUENCE
299  combination for the parameters it's all stuffed into an ad-hoc BIT
300  STRING that we have to pick apart manually. Note that we can't use
301  the ECC p value for a range check because it hasn't been set yet, all
302  that we have at this point is a curve ID */
303  status = readBitStringHole( stream, &length,
305  if( cryptStatusError( status ) )
306  return( status );
307  if( length < MIN_PKCSIZE_ECCPOINT_THRESHOLD || \
308  length > MAX_PKCSIZE_ECCPOINT )
309  return( CRYPT_ERROR_BADDATA );
310  status = sread( stream, buffer, length );
311  if( cryptStatusError( status ) )
312  return( status );
313  status = importECCPoint( &eccKey->eccParam_qx, &eccKey->eccParam_qy,
314  buffer, length, MIN_PKCSIZE_ECC_THRESHOLD,
315  CRYPT_MAX_PKCSIZE_ECC, fieldSize, NULL,
317  zeroise( buffer, length );
318  return( status );
319  }
320 #endif /* USE_ECDH || USE_ECDSA */
321 
322 #ifdef USE_SSH1
323 
324 /* Read SSHv1 public keys:
325 
326  uint32 keysize_bits
327  mpint exponent
328  mpint modulus */
329 
330 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
331 static int readSsh1RsaPublicKey( INOUT STREAM *stream,
332  INOUT CONTEXT_INFO *contextInfoPtr,
333  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
334  {
335  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
336  int length, status;
337 
338  assert( isWritePtr( stream, sizeof( STREAM ) ) );
339  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
340  assert( isWritePtr( actionFlags, sizeof( int ) ) );
341 
342  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
343  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
344 
345  /* Clear return value */
346  *actionFlags = ACTION_PERM_NONE;
347 
348  /* Make sure that the nominal keysize value is valid */
349  status = length = readUint32( stream );
350  if( cryptStatusError( status ) )
351  return( status );
352  if( length < bytesToBits( RSAPARAM_MIN_E + RSAPARAM_MIN_N ) || \
354  return( CRYPT_ERROR_BADDATA );
355 
356  /* Set the maximum permitted actions. SSH keys are only used internally
357  so we restrict the usage to internal-only */
358  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
360 
361  /* Read the SSH public key information */
362  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_e,
365  NULL );
366  if( cryptStatusOK( status ) )
367  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_n,
370  NULL );
371  return( status );
372  }
373 #endif /* USE_SSH1 */
374 
375 #ifdef USE_SSH
376 
377 /* Read SSHv2 public keys:
378 
379  RSA/DSA:
380 
381  string [ server key/certificate ]
382  string "ssh-rsa" "ssh-dss"
383  mpint e p
384  mpint n q
385  mpint g
386  mpint y
387 
388  ECDSA:
389 
390  string [ server key/certificate ]
391  string "ecdsa-sha2-*"
392  string "*" -- The "*" portion from the above field
393  string Q */
394 
395 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
396 static int readSshRsaPublicKey( INOUT STREAM *stream,
397  INOUT CONTEXT_INFO *contextInfoPtr,
398  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
399  {
400  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
401  char buffer[ 16 + 8 ];
402  int length, status;
403 
404  assert( isWritePtr( stream, sizeof( STREAM ) ) );
405  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
406  assert( isWritePtr( actionFlags, sizeof( int ) ) );
407 
408  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
409  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
410 
411  /* Clear return value */
412  *actionFlags = ACTION_PERM_NONE;
413 
414  /* Read the wrapper and make sure that it's OK */
415  readUint32( stream );
416  status = readString32( stream, buffer, 7, &length );
417  if( cryptStatusError( status ) )
418  return( status );
419  if( length != 7 || memcmp( buffer, "ssh-rsa", 7 ) )
420  return( CRYPT_ERROR_BADDATA );
421 
422  /* Set the maximum permitted actions. SSH keys are only used internally
423  so we restrict the usage to internal-only */
424  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
426 
427  /* Read the SSH public key information */
428  status = readBignumInteger32( stream, &rsaKey->rsaParam_e,
430  NULL );
431  if( cryptStatusOK( status ) )
432  status = readBignumInteger32Checked( stream, &rsaKey->rsaParam_n,
434  return( status );
435  }
436 
437 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
438 static int readSshDlpPublicKey( INOUT STREAM *stream,
439  INOUT CONTEXT_INFO *contextInfoPtr,
440  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
441  {
442  PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
443  const BOOLEAN isDH = \
444  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );
445  char buffer[ 16 + 8 ];
446  int length, status;
447 
448  assert( isWritePtr( stream, sizeof( STREAM ) ) );
449  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
450  assert( isWritePtr( actionFlags, sizeof( int ) ) );
451 
452  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
453  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
454  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA ) );
455 
456  /* Clear return value */
457  *actionFlags = ACTION_PERM_NONE;
458 
459  /* Read the wrapper and make sure that it's OK. SSHv2 uses PKCS #3
460  rather than X9.42-style DH keys so we have to treat this algorithm
461  type specially */
462  readUint32( stream );
463  if( isDH )
464  {
465  status = readString32( stream, buffer, 6, &length );
466  if( cryptStatusError( status ) )
467  return( status );
468  if( length != 6 || memcmp( buffer, "ssh-dh", 6 ) )
469  return( CRYPT_ERROR_BADDATA );
470 
471  /* Set the maximum permitted actions. SSH keys are only used
472  internally so we restrict the usage to internal-only. Since DH
473  keys can be both public and private keys we allow both usage
474  types even though technically it's a public key */
475  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
477  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
479 
480  /* Read the SSH public key information */
481  status = readBignumInteger32Checked( stream, &dsaKey->dlpParam_p,
483  if( cryptStatusOK( status ) )
484  status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
486  &dsaKey->dlpParam_p );
487  return( status );
488  }
489 
490  /* It's a standard DLP key, read the wrapper and make sure that it's
491  OK */
492  status = readString32( stream, buffer, 7, &length );
493  if( cryptStatusError( status ) )
494  return( status );
495  if( length != 7 || memcmp( buffer, "ssh-dss", 7 ) )
496  return( CRYPT_ERROR_BADDATA );
497 
498  /* Set the maximum permitted actions. SSH keys are only used internally
499  so we restrict the usage to internal-only */
500  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
502 
503  /* Read the SSH public key information */
504  status = readBignumInteger32Checked( stream, &dsaKey->dlpParam_p,
506  if( cryptStatusOK( status ) )
507  status = readBignumInteger32( stream, &dsaKey->dlpParam_q,
509  &dsaKey->dlpParam_p );
510  if( cryptStatusOK( status ) )
511  status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
513  &dsaKey->dlpParam_p );
514  if( cryptStatusOK( status ) && !isDH )
515  status = readBignumInteger32( stream, &dsaKey->dlpParam_y,
517  &dsaKey->dlpParam_p );
518  return( status );
519  }
520 
521 #if defined( USE_ECDH ) || defined( USE_ECDSA )
522 
523 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
524 static int readSshEccPublicKey( INOUT STREAM *stream,
525  INOUT CONTEXT_INFO *contextInfoPtr,
526  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
527  {
528  PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
529  const BOOLEAN isECDH = \
530  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH );
531  BYTE buffer[ MAX_PKCSIZE_ECCPOINT + 8 ];
532  int length, fieldSize, status;
533 
534  assert( isWritePtr( stream, sizeof( STREAM ) ) );
535  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
536  assert( isWritePtr( actionFlags, sizeof( int ) ) );
537 
538  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
539  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
540 
541  /* Clear return value */
542  *actionFlags = ACTION_PERM_NONE;
543 
544  /* Set the maximum permitted actions. SSH keys are only used
545  internally so we restrict the usage to internal-only. Since ECDH
546  keys can be both public and private keys we allow both usage
547  types even though technically it's a public key */
548  if( isECDH )
549  {
550  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
552  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
554  }
555  else
556  {
557  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
559  }
560 
561  /* Read the wrapper and make sure that it's OK. The key parameter
562  information is repeated twice, so for the overall wrapper we only
563  check for the ECDH/ECDSA algorithm indication, and get the parameter
564  information from the second version, which contains only the
565  parameter string */
566  readUint32( stream );
567  status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
568  if( cryptStatusError( status ) )
569  return( status );
570  if( length < 18 ) /* "ecdh-sha2-nistXXXX" */
571  return( CRYPT_ERROR_BADDATA );
572  if( isECDH )
573  {
574  if( memcmp( buffer, "ecdh-sha2-", 10 ) )
575  return( CRYPT_ERROR_BADDATA );
576  }
577  else
578  {
579  if( memcmp( buffer, "ecdsa-sha2-", 11 ) )
580  return( CRYPT_ERROR_BADDATA );
581  }
582 
583  /* Read and process the parameter information. At this point we know
584  that we've got valid ECC key data, so if we find anything unexpected
585  we report it as an unavailable ECC field size rather than bad data */
586  status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
587  if( cryptStatusError( status ) )
588  return( status );
589  if( length != 8 ) /* "nistXXXX" */
590  return( CRYPT_ERROR_NOTAVAIL );
591  if( !memcmp( buffer, "nistp256", 8 ) )
592  eccKey->curveType = CRYPT_ECCCURVE_P256;
593  else
594  {
595  if( !memcmp( buffer, "nistp384", 8 ) )
596  eccKey->curveType = CRYPT_ECCCURVE_P384;
597  else
598  {
599  if( !memcmp( buffer, "nistp521", 8 ) )
600  eccKey->curveType = CRYPT_ECCCURVE_P521;
601  else
602  return( CRYPT_ERROR_NOTAVAIL );
603  }
604  }
605  status = getECCFieldSize( eccKey->curveType, &fieldSize );
606  if( cryptStatusError( status ) )
607  return( status );
608 
609  /* Read the ECC public key. See the comments in
610  readEccSubjectPublicKey() for why the checks are done the way they
611  are */
612  status = readString32( stream, buffer, MAX_PKCSIZE_ECCPOINT, &length );
613  if( cryptStatusError( status ) )
614  return( status );
615  if( length < MIN_PKCSIZE_ECCPOINT_THRESHOLD || \
616  length > MAX_PKCSIZE_ECCPOINT )
617  return( CRYPT_ERROR_BADDATA );
618  status = importECCPoint( &eccKey->eccParam_qx, &eccKey->eccParam_qy,
619  buffer, length, MIN_PKCSIZE_ECC_THRESHOLD,
620  CRYPT_MAX_PKCSIZE_ECC, fieldSize, NULL,
622  zeroise( buffer, length );
623  return( status );
624  }
625 #endif /* USE_ECDH || USE_ECDSA */
626 
627 #endif /* USE_SSH */
628 
629 #ifdef USE_SSL
630 
631 /* Read SSL public keys:
632 
633  DH:
634  uint16 dh_pLen
635  byte[] dh_p
636  uint16 dh_gLen
637  byte[] dh_g
638  [ uint16 dh_YsLen ]
639  [ byte[] dh_Ys ]
640 
641  ECDH:
642  byte curveType
643  uint16 namedCurve
644  [ uint8 ecPointLen -- NB uint8 not uint16 ]
645  [ byte[] ecPoint ]
646 
647  The DH y value is nominally attached to the DH p and g values but isn't
648  processed at this level since this is a pure PKCS #3 DH key and not a
649  generic DLP key. The same holds for the ECDH Q value */
650 
651 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
652 static int readSslDlpPublicKey( INOUT STREAM *stream,
653  INOUT CONTEXT_INFO *contextInfoPtr,
654  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
655  {
656  PKC_INFO *dhKey = contextInfoPtr->ctxPKC;
657  int status;
658 
659  assert( isWritePtr( stream, sizeof( STREAM ) ) );
660  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
661  assert( isWritePtr( actionFlags, sizeof( int ) ) );
662 
663  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
664  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );
665 
666  /* Clear return value */
667  *actionFlags = ACTION_PERM_NONE;
668 
669  /* Set the maximum permitted actions. SSL keys are only used
670  internally so we restrict the usage to internal-only. Since DH
671  keys can be both public and private keys we allow both usage
672  types even though technically it's a public key */
673  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
675  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
677 
678  /* Read the SSL public key information */
679  status = readBignumInteger16UChecked( stream, &dhKey->dlpParam_p,
681  if( cryptStatusOK( status ) )
682  status = readBignumInteger16U( stream, &dhKey->dlpParam_g,
684  &dhKey->dlpParam_p );
685  return( status );
686  }
687 
688 #if defined( USE_ECDH )
689 
690 static const MAP_TABLE sslCurveInfo[] = {
691  { 19, CRYPT_ECCCURVE_P192 },
692  { 21, CRYPT_ECCCURVE_P224 },
693  { 23, CRYPT_ECCCURVE_P256 },
694  { 24, CRYPT_ECCCURVE_P384 },
695  { 25, CRYPT_ECCCURVE_P521 },
696  { CRYPT_ERROR, 0 },
697  { CRYPT_ERROR, 0 }
698  };
699 
700 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
701 static int getEccSslInfoTbl( OUT const MAP_TABLE **sslInfoTblPtr,
702  OUT_INT_Z int *noSslInfoTblEntries )
703  {
704  assert( isReadPtr( sslInfoTblPtr, sizeof( MAP_TABLE * ) ) );
705  assert( isWritePtr( noSslInfoTblEntries, sizeof( int ) ) );
706 
707  *sslInfoTblPtr = sslCurveInfo;
708  *noSslInfoTblEntries = FAILSAFE_ARRAYSIZE( sslCurveInfo, MAP_TABLE );
709 
710  return( CRYPT_OK );
711  }
712 
713 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
714 static int readSslEccPublicKey( INOUT STREAM *stream,
715  INOUT CONTEXT_INFO *contextInfoPtr,
716  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
717  {
718  PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
719  const MAP_TABLE *sslCurveInfoPtr;
720  int value, curveID, sslCurveInfoNoEntries, status;
721 
722  assert( isWritePtr( stream, sizeof( STREAM ) ) );
723  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
724  assert( isWritePtr( actionFlags, sizeof( int ) ) );
725 
726  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
727  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH );
728 
729  /* Clear return value */
730  *actionFlags = ACTION_PERM_NONE;
731 
732  /* Set the maximum permitted actions. SSL keys are only used
733  internally so we restrict the usage to internal-only. Since ECDH
734  keys can be both public and private keys we allow both usage
735  types even though technically it's a public key */
736  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
738  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
740 
741  /* Read the SSL public key information */
742  status = value = sgetc( stream );
743  if( cryptStatusError( status ) )
744  return( status );
745  if( value != 0x03 ) /* NamedCurve */
746  return( CRYPT_ERROR_BADDATA );
747  status = value = readUint16( stream );
748  if( cryptStatusError( status ) )
749  return( status );
750 
751  /* Look up the curve ID based on the SSL NamedCurve ID */
752  status = getEccSslInfoTbl( &sslCurveInfoPtr, &sslCurveInfoNoEntries );
753  if( cryptStatusError( status ) )
754  return( status );
755  status = mapValue( value, &curveID, sslCurveInfoPtr,
756  sslCurveInfoNoEntries );
757  if( cryptStatusError( status ) )
758  return( status );
759  eccKey->curveType = curveID;
760  return( CRYPT_OK );
761  }
762 #endif /* USE_ECDH */
763 
764 #endif /* USE_SSL */
765 
766 #ifdef USE_PGP
767 
768 /* Read PGP public keys:
769 
770  byte version
771  uint32 creationTime
772  [ uint16 validity - version 2 or 3 only ]
773  byte RSA DSA Elgamal
774  mpi n p p
775  mpi e q g
776  mpi g y
777  mpi y */
778 
779 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
780 static int readPgpRsaPublicKey( INOUT STREAM *stream,
781  INOUT CONTEXT_INFO *contextInfoPtr,
782  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
783  {
784  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
785  time_t creationTime;
786  int value, status;
787 
788  assert( isWritePtr( stream, sizeof( STREAM ) ) );
789  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
790  assert( isWritePtr( actionFlags, sizeof( int ) ) );
791 
792  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
793  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
794 
795  /* Clear return value */
796  *actionFlags = ACTION_PERM_NONE;
797 
798  /* Read the header info */
799  status = value = sgetc( stream );
800  if( cryptStatusError( status ) )
801  return( status );
802  if( value != PGP_VERSION_2 && value != PGP_VERSION_3 && \
803  value != PGP_VERSION_OPENPGP )
804  return( CRYPT_ERROR_BADDATA );
805  status = readUint32Time( stream, &creationTime );
806  if( cryptStatusError( status ) )
807  return( status );
808  rsaKey->pgpCreationTime = creationTime;
809  if( value == PGP_VERSION_2 || value == PGP_VERSION_3 )
810  {
811  /* Skip the validity period */
812  sSkip( stream, 2 );
813  }
814 
815  /* Set the maximum permitted actions. If there are no restrictions we
816  allow external usage, if the keys are encryption-only or signature-
817  only we make the usage internal-only because of RSA's signature/
818  encryption duality. If the key is a pure public key rather than
819  merely the public portions of a private key the actions will be
820  restricted by higher-level code to signature-check only */
821  status = value = sgetc( stream );
822  if( cryptStatusError( status ) )
823  return( status );
824  if( value != PGP_ALGO_RSA && value != PGP_ALGO_RSA_ENCRYPT && \
825  value != PGP_ALGO_RSA_SIGN )
826  return( CRYPT_ERROR_BADDATA );
827  *actionFlags = ACTION_PERM_NONE;
828  if( value != PGP_ALGO_RSA_SIGN )
829  {
830  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
831  ACTION_PERM_ALL ) | \
832  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
833  ACTION_PERM_ALL );
834  }
835  if( value != PGP_ALGO_RSA_ENCRYPT )
836  {
837  *actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
838  ACTION_PERM_ALL ) | \
839  MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
840  ACTION_PERM_ALL );
841  }
842  if( value != PGP_ALGO_RSA )
843  *actionFlags = MK_ACTION_PERM_NONE_EXTERNAL( *actionFlags );
844 
845  /* Read the PGP public key information */
846  status = readBignumInteger16UbitsChecked( stream, &rsaKey->rsaParam_n,
849  if( cryptStatusOK( status ) )
850  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_e,
853  &rsaKey->rsaParam_n );
854  return( status );
855  }
856 
857 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
858 static int readPgpDlpPublicKey( INOUT STREAM *stream,
859  INOUT CONTEXT_INFO *contextInfoPtr,
860  OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
861  {
862  PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
863  time_t creationTime;
864  int value, status;
865 
866  assert( isWritePtr( stream, sizeof( STREAM ) ) );
867  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
868  assert( isWritePtr( actionFlags, sizeof( int ) ) );
869 
870  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
871  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
872  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
873 
874  /* Clear return value */
875  *actionFlags = ACTION_PERM_NONE;
876 
877  /* Read the header info */
878  status = value = sgetc( stream );
879  if( cryptStatusError( status ) )
880  return( status );
881  if( value != PGP_VERSION_OPENPGP )
882  return( CRYPT_ERROR_BADDATA );
883  status = readUint32Time( stream, &creationTime );
884  if( cryptStatusError( status ) )
885  return( status );
886  dlpKey->pgpCreationTime = creationTime;
887 
888  /* Set the maximum permitted actions. Because of the special-case data
889  formatting requirements for DLP algorithms we make the usage
890  internal-only. If the key is a pure public key rather than merely
891  the public portions of a private key the actions will be restricted
892  by higher-level code to signature-check only */
893  status = value = sgetc( stream );
894  if( cryptStatusError( status ) )
895  return( status );
896  if( value != PGP_ALGO_DSA && value != PGP_ALGO_ELGAMAL )
897  return( CRYPT_ERROR_BADDATA );
898  if( value == PGP_ALGO_DSA )
899  {
900  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
902  MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
904  }
905  else
906  {
907  *actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
909  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
911  }
912 
913  /* Read the PGP public key information */
914  status = readBignumInteger16UbitsChecked( stream, &dlpKey->dlpParam_p,
917  if( cryptStatusOK( status ) && value == PGP_ALGO_DSA )
918  status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_q,
921  &dlpKey->dlpParam_p );
922  if( cryptStatusOK( status ) )
923  status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_g,
926  &dlpKey->dlpParam_p );
927  if( cryptStatusOK( status ) )
928  status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_y,
931  &dlpKey->dlpParam_p );
932  return( status );
933  }
934 #endif /* USE_PGP */
935 
936 /* Umbrella public-key read functions */
937 
939 static int completePubkeyRead( INOUT CONTEXT_INFO *contextInfoPtr,
940  IN_FLAGS( ACTION_PERM ) const int actionFlags )
941  {
942  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
943 
944  REQUIRES( actionFlags > ACTION_PERM_FLAG_NONE && \
945  actionFlags < ACTION_PERM_FLAG_MAX );
946 
947  /* If it's statically-initialised context data used in the self-test
948  there's no corresponding cryptlib object and we're done */
949  if( contextInfoPtr->flags & CONTEXT_FLAG_STATICCONTEXT )
950  return( CRYPT_OK );
951 
952  /* Set the action permissions for the context */
953  return( krnlSendMessage( contextInfoPtr->objectHandle,
955  ( MESSAGE_CAST ) &actionFlags,
956  CRYPT_IATTRIBUTE_ACTIONPERMS ) );
957  }
958 
959 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
960 static int readPublicKeyRsaFunction( INOUT STREAM *stream,
961  INOUT CONTEXT_INFO *contextInfoPtr,
962  IN_ENUM( KEYFORMAT ) \
963  const KEYFORMAT_TYPE formatType )
964  {
965  int actionFlags, status;
966 
967  assert( isWritePtr( stream, sizeof( STREAM ) ) );
968  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
969 
970  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
971  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
972  REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
973 
974  switch( formatType )
975  {
976  case KEYFORMAT_CERT:
977  status = readRsaSubjectPublicKey( stream, contextInfoPtr,
978  &actionFlags );
979  break;
980 
981 #ifdef USE_SSH1
982  case KEYFORMAT_SSH1:
983  status = readSsh1RsaPublicKey( stream, contextInfoPtr,
984  &actionFlags );
985  break;
986 #endif /* USE_SSH1 */
987 
988 #ifdef USE_SSH
989  case KEYFORMAT_SSH:
990  status = readSshRsaPublicKey( stream, contextInfoPtr,
991  &actionFlags );
992  break;
993 #endif /* USE_SSH */
994 
995 #ifdef USE_PGP
996  case KEYFORMAT_PGP:
997  status = readPgpRsaPublicKey( stream, contextInfoPtr,
998  &actionFlags );
999  break;
1000 #endif /* USE_PGP */
1001 
1002  default:
1003  retIntError();
1004  }
1005  if( cryptStatusError( status ) )
1006  return( status );
1007  return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1008  }
1009 
1010 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1011 static int readPublicKeyDlpFunction( INOUT STREAM *stream,
1012  INOUT CONTEXT_INFO *contextInfoPtr,
1013  IN_ENUM( KEYFORMAT ) \
1014  const KEYFORMAT_TYPE formatType )
1015  {
1016  int actionFlags, status;
1017 
1018  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1019  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1020 
1021  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1022  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
1023  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
1024  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
1025  REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1026 
1027  switch( formatType )
1028  {
1029  case KEYFORMAT_CERT:
1030  status = readDlpSubjectPublicKey( stream, contextInfoPtr,
1031  &actionFlags );
1032  break;
1033 
1034 #ifdef USE_SSH
1035  case KEYFORMAT_SSH:
1036  status = readSshDlpPublicKey( stream, contextInfoPtr,
1037  &actionFlags );
1038  break;
1039 #endif /* USE_SSH */
1040 
1041 #ifdef USE_SSL
1042  case KEYFORMAT_SSL:
1043  status = readSslDlpPublicKey( stream, contextInfoPtr,
1044  &actionFlags );
1045  break;
1046 #endif /* USE_SSL */
1047 
1048 #ifdef USE_PGP
1049  case KEYFORMAT_PGP:
1050  status = readPgpDlpPublicKey( stream, contextInfoPtr,
1051  &actionFlags );
1052  break;
1053 #endif /* USE_PGP */
1054 
1055  default:
1056  retIntError();
1057  }
1058  if( cryptStatusError( status ) )
1059  return( status );
1060  return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1061  }
1062 
1063 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1064 
1065 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1066 static int readPublicKeyEccFunction( INOUT STREAM *stream,
1067  INOUT CONTEXT_INFO *contextInfoPtr,
1068  IN_ENUM( KEYFORMAT ) \
1069  const KEYFORMAT_TYPE formatType )
1070  {
1071  int actionFlags, status;
1072 
1073  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1074  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1075 
1076  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1077  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA || \
1078  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH ) );
1079  REQUIRES( formatType == KEYFORMAT_CERT || formatType == KEYFORMAT_SSL || \
1080  formatType == KEYFORMAT_SSH );
1081 
1082  switch( formatType )
1083  {
1084  case KEYFORMAT_CERT:
1085  status = readEccSubjectPublicKey( stream, contextInfoPtr,
1086  &actionFlags );
1087  break;
1088 
1089 #ifdef USE_SSL
1090  case KEYFORMAT_SSL:
1091  status = readSslEccPublicKey( stream, contextInfoPtr,
1092  &actionFlags );
1093  break;
1094 #endif /* USE_SSL */
1095 
1096 #ifdef USE_SSH
1097  case KEYFORMAT_SSH:
1098  status = readSshEccPublicKey( stream, contextInfoPtr,
1099  &actionFlags );
1100  break;
1101 #endif /* USE_SSH */
1102 
1103  default:
1104  retIntError();
1105  }
1106  if( cryptStatusError( status ) )
1107  return( status );
1108  return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1109  }
1110 #endif /* USE_ECDH || USE_ECDSA */
1111 
1112 /****************************************************************************
1113 * *
1114 * Read Private Keys *
1115 * *
1116 ****************************************************************************/
1117 
1118 /* Read private key components. This function assumes that the public
1119  portion of the context has already been set up */
1120 
1121 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1122 static int readRsaPrivateKey( INOUT STREAM *stream,
1123  INOUT CONTEXT_INFO *contextInfoPtr )
1124  {
1125  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
1126  int status;
1127 
1128  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1129  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1130 
1131  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1132  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
1133 
1134  /* Read the header */
1135  status = readSequence( stream, NULL );
1136  if( cryptStatusOK( status ) && \
1137  peekTag( stream ) == MAKE_CTAG( 0 ) )
1138  {
1139  /* Erroneously written in older code */
1140  status = readConstructed( stream, NULL, 0 );
1141  }
1142  if( cryptStatusError( status ) )
1143  return( status );
1144 
1145  /* Read the key components */
1146  if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 0 ) )
1147  {
1148  /* The public components may already have been read when we read a
1149  corresponding public key or certificate so we only read them if
1150  they're not already present */
1151  if( BN_is_zero( &rsaKey->rsaParam_n ) && \
1152  BN_is_zero( &rsaKey->rsaParam_e ) )
1153  {
1154  status = readBignumTag( stream, &rsaKey->rsaParam_n,
1156  NULL, 0 );
1157  if( cryptStatusOK( status ) )
1158  {
1159  status = readBignumTag( stream, &rsaKey->rsaParam_e,
1161  &rsaKey->rsaParam_n, 1 );
1162  }
1163  }
1164  else
1165  {
1166  /* The key components are already present, skip them */
1167  REQUIRES( !BN_is_zero( &rsaKey->rsaParam_n ) && \
1168  !BN_is_zero( &rsaKey->rsaParam_e ) );
1169  readUniversal( stream );
1170  status = readUniversal( stream );
1171  }
1172  }
1173  if( cryptStatusError( status ) )
1174  return( status );
1175  if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 2 ) )
1176  status = readBignumTag( stream, &rsaKey->rsaParam_d,
1178  &rsaKey->rsaParam_n, 2 );
1179  if( cryptStatusOK( status ) )
1180  status = readBignumTag( stream, &rsaKey->rsaParam_p,
1182  &rsaKey->rsaParam_n, 3 );
1183  if( cryptStatusOK( status ) )
1184  status = readBignumTag( stream, &rsaKey->rsaParam_q,
1186  &rsaKey->rsaParam_n, 4 );
1187  if( cryptStatusError( status ) )
1188  return( status );
1189  if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 5 ) )
1190  {
1191  status = readBignumTag( stream, &rsaKey->rsaParam_exponent1,
1193  &rsaKey->rsaParam_n, 5 );
1194  if( cryptStatusOK( status ) )
1195  status = readBignumTag( stream, &rsaKey->rsaParam_exponent2,
1197  &rsaKey->rsaParam_n, 6 );
1198  if( cryptStatusOK( status ) )
1199  status = readBignumTag( stream, &rsaKey->rsaParam_u,
1201  &rsaKey->rsaParam_n, 7 );
1202  }
1203  return( status );
1204  }
1205 
1206 #ifdef USE_PKCS12
1207 
1208 #define OID_X509_KEYUSAGE MKOID( "\x06\x03\x55\x1D\x0F" )
1209 
1210 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1211 static int readRsaPrivateKeyOld( INOUT STREAM *stream,
1212  INOUT CONTEXT_INFO *contextInfoPtr )
1213  {
1214  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
1215  const int startPos = stell( stream );
1216  int length, endPos, iterationCount, status;
1217 
1218  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1219  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1220 
1221  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1222  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
1223 
1224  /* Skip the PKCS #8 wrapper. When we read the OCTET STRING
1225  encapsulation we use MIN_PKCSIZE_THRESHOLD rather than MIN_PKCSIZE
1226  so that a too-short key will get to readBignumChecked(), which
1227  returns an appropriate error code */
1228  readSequence( stream, &length ); /* Outer SEQUENCE */
1229  readShortInteger( stream, NULL ); /* Version */
1230  readUniversal( stream ); /* AlgorithmIdentifier */
1231  status = readOctetStringHole( stream, NULL,
1232  ( 2 * MIN_PKCSIZE_THRESHOLD ) + \
1233  ( 5 * ( MIN_PKCSIZE_THRESHOLD / 2 ) ),
1234  DEFAULT_TAG );
1235  if( cryptStatusError( status ) ) /* OCTET STRING encapsulation */
1236  return( status );
1237 
1238  /* Read the header and key components */
1239  readSequence( stream, NULL );
1240  readShortInteger( stream, NULL );
1241  status = readBignumChecked( stream, &rsaKey->rsaParam_n,
1243  NULL );
1244  if( cryptStatusOK( status ) )
1245  status = readBignum( stream, &rsaKey->rsaParam_e,
1247  &rsaKey->rsaParam_n );
1248  if( cryptStatusOK( status ) )
1249  status = readBignum( stream, &rsaKey->rsaParam_d,
1251  &rsaKey->rsaParam_n );
1252  if( cryptStatusOK( status ) )
1253  status = readBignum( stream, &rsaKey->rsaParam_p,
1255  &rsaKey->rsaParam_n );
1256  if( cryptStatusOK( status ) )
1257  status = readBignum( stream, &rsaKey->rsaParam_q,
1259  &rsaKey->rsaParam_n );
1260  if( cryptStatusOK( status ) )
1261  status = readBignum( stream, &rsaKey->rsaParam_exponent1,
1263  &rsaKey->rsaParam_n );
1264  if( cryptStatusOK( status ) )
1265  status = readBignum( stream, &rsaKey->rsaParam_exponent2,
1267  &rsaKey->rsaParam_n );
1268  if( cryptStatusOK( status ) )
1269  status = readBignum( stream, &rsaKey->rsaParam_u,
1271  &rsaKey->rsaParam_n );
1272  if( cryptStatusError( status ) )
1273  return( status );
1274 
1275  /* Check whether there are any attributes present */
1276  if( stell( stream ) >= startPos + length )
1277  return( CRYPT_OK );
1278 
1279  /* Read the attribute wrapper */
1280  status = readConstructed( stream, &length, 0 );
1281  if( cryptStatusError( status ) )
1282  return( status );
1283  endPos = stell( stream ) + length;
1284 
1285  /* Read the collection of attributes. Unlike any other key-storage
1286  format, PKCS #8 stores the key usage information as an X.509
1287  attribute alongside the encrypted private key data, so we have to
1288  process whatever attributes may be present in order to find the
1289  keyUsage (if there is any) in order to set the object action
1290  permissions */
1291  for( iterationCount = 0;
1292  stell( stream ) < endPos && \
1293  iterationCount < FAILSAFE_ITERATIONS_MED;
1294  iterationCount++ )
1295  {
1296  BYTE oid[ MAX_OID_SIZE + 8 ];
1297  int oidLength, actionFlags, value;
1298 
1299  /* Read the attribute. Since there's only one attribute type that
1300  we can use, we hardcode the read in here rather than performing a
1301  general-purpose attribute read */
1302  readSequence( stream, NULL );
1303  status = readEncodedOID( stream, oid, MAX_OID_SIZE, &oidLength,
1305  if( cryptStatusError( status ) )
1306  return( status );
1307 
1308  /* If it's not a key-usage attribute, we can't do much with it */
1309  if( oidLength != sizeofOID( OID_X509_KEYUSAGE ) || \
1310  memcmp( oid, OID_X509_KEYUSAGE, oidLength ) )
1311  {
1312  status = readUniversal( stream );
1313  if( cryptStatusError( status ) )
1314  return( status );
1315  continue;
1316  }
1317 
1318  /* Read the keyUsage attribute and convert it into cryptlib action
1319  permissions */
1320  readSet( stream, NULL );
1321  status = readBitString( stream, &value );
1322  if( cryptStatusError( status ) )
1323  return( status );
1324  actionFlags = ACTION_PERM_NONE;
1325  if( value & ( KEYUSAGE_SIGN | KEYUSAGE_CA ) )
1326  {
1327  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
1328  ACTION_PERM_ALL ) | \
1329  MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
1330  ACTION_PERM_ALL );
1331  }
1332  if( value & KEYUSAGE_CRYPT )
1333  {
1334  actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
1335  ACTION_PERM_ALL ) | \
1336  MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
1337  ACTION_PERM_ALL );
1338  }
1339  if( actionFlags == ACTION_PERM_NONE )
1340  return( CRYPT_ERROR_NOTAVAIL );
1341  status = krnlSendMessage( contextInfoPtr->objectHandle,
1342  IMESSAGE_SETATTRIBUTE, &actionFlags,
1343  CRYPT_IATTRIBUTE_ACTIONPERMS );
1344  if( cryptStatusError( status ) )
1345  return( status );
1346  }
1347  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
1348 
1349  return( CRYPT_OK );
1350  }
1351 #endif /* USE_PKCS12 */
1352 
1353 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1354 static int readDlpPrivateKey( INOUT STREAM *stream,
1355  INOUT CONTEXT_INFO *contextInfoPtr )
1356  {
1357  PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
1358 
1359  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1360  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1361 
1362  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1363  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
1364  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
1365  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
1366 
1367  /* Read the key components */
1368  if( peekTag( stream ) == BER_SEQUENCE )
1369  {
1370  /* Erroneously written in older code */
1371  readSequence( stream, NULL );
1372  return( readBignumTag( stream, &dlpKey->dlpParam_x,
1374  &dlpKey->dlpParam_p, 0 ) );
1375  }
1376  return( readBignum( stream, &dlpKey->dlpParam_x,
1378  &dlpKey->dlpParam_p ) );
1379  }
1380 
1381 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1382 
1383 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1384 static int readEccPrivateKey( INOUT STREAM *stream,
1385  INOUT CONTEXT_INFO *contextInfoPtr )
1386  {
1387  PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
1388 
1389  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1390  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1391 
1392  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1393  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
1394 
1395  /* Read the key components. Note that we can't use the ECC p value for
1396  a range check because it hasn't been set yet, all that we have at
1397  this point is a curve ID */
1398  return( readBignum( stream, &eccKey->eccParam_d,
1399  ECCPARAM_MIN_D, ECCPARAM_MAX_D, NULL ) );
1400  }
1401 #endif /* USE_ECDH || USE_ECDSA */
1402 
1403 #ifdef USE_PGP
1404 
1405 /* Read PGP private key components. This function assumes that the public
1406  portion of the context has already been set up */
1407 
1408 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1409 static int readPgpRsaPrivateKey( INOUT STREAM *stream,
1410  INOUT CONTEXT_INFO *contextInfoPtr )
1411  {
1412  PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
1413  int status;
1414 
1415  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1416  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1417 
1418  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1419  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
1420 
1421  /* Read the PGP private key information */
1422  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_d,
1425  &rsaKey->rsaParam_n );
1426  if( cryptStatusOK( status ) )
1427  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_p,
1430  &rsaKey->rsaParam_n );
1431  if( cryptStatusOK( status ) )
1432  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_q,
1435  &rsaKey->rsaParam_n );
1436  if( cryptStatusOK( status ) )
1437  status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_u,
1440  &rsaKey->rsaParam_n );
1441  return( status );
1442  }
1443 
1444 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1445 static int readPgpDlpPrivateKey( INOUT STREAM *stream,
1446  INOUT CONTEXT_INFO *contextInfoPtr )
1447  {
1448  PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
1449 
1450  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1451  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1452 
1453  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1454  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
1455  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
1456 
1457  /* Read the PGP private key information */
1458  return( readBignumInteger16Ubits( stream, &dlpKey->dlpParam_x,
1461  &dlpKey->dlpParam_p ) );
1462  }
1463 #endif /* USE_PGP */
1464 
1465 /* Umbrella private-key read functions */
1466 
1467 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1468 static int readPrivateKeyRsaFunction( INOUT STREAM *stream,
1469  INOUT CONTEXT_INFO *contextInfoPtr,
1470  IN_ENUM( KEYFORMAT ) \
1471  const KEYFORMAT_TYPE formatType )
1472  {
1473  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1474  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1475 
1476  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1477  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
1478  REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1479 
1480  switch( formatType )
1481  {
1482  case KEYFORMAT_PRIVATE:
1483  return( readRsaPrivateKey( stream, contextInfoPtr ) );
1484 
1485 #ifdef USE_PKCS12
1486  case KEYFORMAT_PRIVATE_OLD:
1487  return( readRsaPrivateKeyOld( stream, contextInfoPtr ) );
1488 #endif /* USE_PKCS12 */
1489 
1490 #ifdef USE_PGP
1491  case KEYFORMAT_PGP:
1492  return( readPgpRsaPrivateKey( stream, contextInfoPtr ) );
1493 #endif /* USE_PGP */
1494  }
1495 
1496  retIntError();
1497  }
1498 
1499 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1500 static int readPrivateKeyDlpFunction( INOUT STREAM *stream,
1501  INOUT CONTEXT_INFO *contextInfoPtr,
1502  IN_ENUM( KEYFORMAT ) \
1503  const KEYFORMAT_TYPE formatType )
1504  {
1505  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1506  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1507 
1508  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1509  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
1510  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
1511  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
1512  REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1513 
1514  switch( formatType )
1515  {
1516  case KEYFORMAT_PRIVATE:
1517  return( readDlpPrivateKey( stream, contextInfoPtr ) );
1518 
1519 #ifdef USE_PGP
1520  case KEYFORMAT_PGP:
1521  return( readPgpDlpPrivateKey( stream, contextInfoPtr ) );
1522 #endif /* USE_PGP */
1523  }
1524 
1525  retIntError();
1526  }
1527 
1528 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1529 
1530 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
1531 static int readPrivateKeyEccFunction( INOUT STREAM *stream,
1532  INOUT CONTEXT_INFO *contextInfoPtr,
1533  IN_ENUM( KEYFORMAT ) \
1534  const KEYFORMAT_TYPE formatType )
1535  {
1536  assert( isWritePtr( stream, sizeof( STREAM ) ) );
1537  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1538 
1539  REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1540  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
1541  REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1542 
1543  switch( formatType )
1544  {
1545  case KEYFORMAT_PRIVATE:
1546  return( readEccPrivateKey( stream, contextInfoPtr ) );
1547  }
1548 
1549  retIntError();
1550  }
1551 #endif /* USE_ECDH || USE_ECDSA */
1552 
1553 /****************************************************************************
1554 * *
1555 * Read DL Values *
1556 * *
1557 ****************************************************************************/
1558 
1559 /* Unlike the simpler RSA PKC, DL-based PKCs produce a pair of values that
1560  need to be encoded as structured data. The following two functions
1561  perform this en/decoding. SSH assumes that DLP values are two fixed-size
1562  blocks of 20 bytes so we can't use the normal read/write routines to
1563  handle these values */
1564 
1565 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 5 ) ) \
1566 static int decodeDLValuesFunction( IN_BUFFER( bufSize ) const BYTE *buffer,
1567  IN_LENGTH_SHORT_MIN( 32 ) const int bufSize,
1568  OUT BIGNUM *value1,
1569  OUT BIGNUM *value2,
1570  const BIGNUM *maxRange,
1571  IN_ENUM( CRYPT_FORMAT ) \
1572  const CRYPT_FORMAT_TYPE formatType )
1573  {
1574  STREAM stream;
1575  int status;
1576 
1577  assert( isReadPtr( buffer, bufSize ) );
1578  assert( isWritePtr( value1, sizeof( BIGNUM ) ) );
1579  assert( isWritePtr( value2, sizeof( BIGNUM ) ) );
1580  assert( isReadPtr( maxRange, sizeof( BIGNUM ) ) );
1581 
1582  REQUIRES( bufSize >= 32 && bufSize < MAX_INTLENGTH_SHORT );
1583  REQUIRES( formatType > CRYPT_FORMAT_NONE && \
1584  formatType < CRYPT_FORMAT_LAST );
1585 
1586  sMemConnect( &stream, buffer, bufSize );
1587 
1588  /* Read the DL components from the buffer and make sure that they're
1589  valid, i.e. that they're in the range [1...maxRange - 1] (the lower
1590  bound is actually DLPPARAM_MIN_SIG_x and not 1, which is > 100 bits).
1591  Although nominally intended for DLP algorithms the DLPPARAM_MIN_SIG_x
1592  values also work for ECC ones since they're also in the DLP family */
1593  switch( formatType )
1594  {
1595  case CRYPT_FORMAT_CRYPTLIB:
1596  readSequence( &stream, NULL );
1597  status = readBignum( &stream, value1, DLPPARAM_MIN_SIG_R,
1598  CRYPT_MAX_PKCSIZE, maxRange );
1599  if( cryptStatusError( status ) )
1600  break;
1601  status = readBignum( &stream, value2, DLPPARAM_MIN_SIG_S,
1602  CRYPT_MAX_PKCSIZE, maxRange );
1603  break;
1604 
1605 #ifdef USE_PGP
1606  case CRYPT_FORMAT_PGP:
1607  status = readBignumInteger16Ubits( &stream, value1,
1610  maxRange );
1611  if( cryptStatusError( status ) )
1612  break;
1613  status = readBignumInteger16Ubits( &stream, value2,
1616  maxRange );
1617  break;
1618 #endif /* USE_PGP */
1619 
1620 #ifdef USE_SSH
1621  case CRYPT_IFORMAT_SSH:
1622  status = importBignum( value1, buffer, 20, DLPPARAM_MIN_SIG_R,
1623  20, maxRange, KEYSIZE_CHECK_NONE );
1624  if( cryptStatusError( status ) )
1625  break;
1626  status = importBignum( value2, buffer + 20, 20, DLPPARAM_MIN_SIG_S,
1627  20, maxRange, KEYSIZE_CHECK_NONE );
1628  break;
1629 #endif /* USE_SSH */
1630 
1631  default:
1632  retIntError();
1633  }
1634 
1635  /* Clean up */
1636  sMemDisconnect( &stream );
1637  return( status );
1638  }
1639 
1640 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 5 ) ) \
1641 static int decodeECDLValuesFunction( IN_BUFFER( bufSize ) const BYTE *buffer,
1642  IN_LENGTH_SHORT_MIN( 32 ) const int bufSize,
1643  OUT BIGNUM *value1,
1644  OUT BIGNUM *value2,
1645  const BIGNUM *maxRange,
1646  IN_ENUM( CRYPT_FORMAT ) \
1647  const CRYPT_FORMAT_TYPE formatType )
1648  {
1649  STREAM stream;
1650  int status;
1651 
1652  assert( isReadPtr( buffer, bufSize ) );
1653  assert( isWritePtr( value1, sizeof( BIGNUM ) ) );
1654  assert( isWritePtr( value2, sizeof( BIGNUM ) ) );
1655  assert( isReadPtr( maxRange, sizeof( BIGNUM ) ) );
1656 
1657  REQUIRES( bufSize >= 32 && bufSize < MAX_INTLENGTH_SHORT );
1658  REQUIRES( formatType > CRYPT_FORMAT_NONE && \
1659  formatType < CRYPT_FORMAT_LAST );
1660 
1661  /* In most cases the DLP and ECDLP formats are identical and we can just
1662  pass the call on to the DLP form, however SSH uses totally different
1663  signature formats depending on whether the signature is DSA or ECDSA,
1664  so we handle the SSH format explicitly here */
1665  if( formatType != CRYPT_IFORMAT_SSH )
1666  {
1667  return( decodeDLValuesFunction( buffer, bufSize, value1, value2,
1668  maxRange, formatType ) );
1669  }
1670  sMemConnect( &stream, buffer, bufSize );
1671  status = readBignumInteger32( &stream, value1, ECCPARAM_MIN_SIG_R,
1672  CRYPT_MAX_PKCSIZE_ECC, maxRange );
1673  if( cryptStatusOK( status ) )
1674  {
1675  status = readBignumInteger32( &stream, value2, ECCPARAM_MIN_SIG_S,
1676  CRYPT_MAX_PKCSIZE_ECC, maxRange );
1677  }
1678  sMemDisconnect( &stream );
1679  return( status );
1680  }
1681 
1682 /****************************************************************************
1683 * *
1684 * Context Access Routines *
1685 * *
1686 ****************************************************************************/
1687 
1688 STDC_NONNULL_ARG( ( 1 ) ) \
1689 void initKeyRead( INOUT CONTEXT_INFO *contextInfoPtr )
1690  {
1691  const CRYPT_ALGO_TYPE cryptAlgo = contextInfoPtr->capabilityInfo->cryptAlgo;
1692  PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
1693 
1694  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1695 
1696  REQUIRES_V( contextInfoPtr->type == CONTEXT_PKC );
1697 
1698  /* Set the access method pointers */
1699  if( isDlpAlgo( cryptAlgo ) )
1700  {
1701  pkcInfo->readPublicKeyFunction = readPublicKeyDlpFunction;
1702  pkcInfo->readPrivateKeyFunction = readPrivateKeyDlpFunction;
1703  pkcInfo->decodeDLValuesFunction = decodeDLValuesFunction;
1704 
1705  return;
1706  }
1707 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1708  if( isEccAlgo( cryptAlgo ) )
1709  {
1710  pkcInfo->readPublicKeyFunction = readPublicKeyEccFunction;
1711  pkcInfo->readPrivateKeyFunction = readPrivateKeyEccFunction;
1712  pkcInfo->decodeDLValuesFunction = decodeECDLValuesFunction;
1713 
1714  return;
1715  }
1716 #endif /* USE_ECDH || USE_ECDSA */
1717  pkcInfo->readPublicKeyFunction = readPublicKeyRsaFunction;
1718  pkcInfo->readPrivateKeyFunction = readPrivateKeyRsaFunction;
1719  }
1720 #else
1721 
1723 void initKeyRead( INOUT CONTEXT_INFO *contextInfoPtr )
1724  {
1725  }
1726 #endif /* USE_PKC */