1 /****************************************************************************
2 *																			*
3 *							Public Key Read Routines						*
4 *						Copyright Peter Gutmann 1992-2012					*
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 /* The DLP algorithms split the key components over the information in the
25    AlgorithmIdentifier and the actual public/private key components, with the
26    (p, q, g) set classed as domain parameters and included in the
27    AlgorithmIdentifier and y being the actual key.
28 
29 	params = SEQ {
30 		p INTEGER,
31 		q INTEGER,				-- q for DSA
32 		g INTEGER,				-- g for DSA
33 		j INTEGER OPTIONAL,		-- X9.42 only
34 		validationParams [...]	-- X9.42 only
35 		}
36 
37 	key = y INTEGER				-- g^x mod p
38 
39    For peculiar historical reasons (copying errors and the use of obsolete
40    drafts as reference material) the X9.42 interpretation used in PKIX
41    reverses the second two parameters from FIPS 186 (so it uses p, g, q
42    instead of p, q, g), so when we read/write the parameter information we
43    have to switch the order in which we read the values if the algorithm
44    isn't DSA */
45 
46 #define hasReversedParams( cryptAlgo ) \
47 		( ( cryptAlgo ) == CRYPT_ALGO_DH || \
48 		  ( cryptAlgo ) == CRYPT_ALGO_ELGAMAL )
49 
50 #ifdef USE_PKC
51 
52 /****************************************************************************
53 *																			*
54 *							Read X.509 Public Keys							*
55 *																			*
56 ****************************************************************************/
57 
58 #ifdef USE_INT_ASN1
59 
60 /* Read X.509 SubjectPublicKeyInfo public keys:
61 
62 	SubjectPublicKeyInfo  ::=  SEQUENCE  {
63 		algorithm			AlgorithmIdentifier,
64 		subjectPublicKey	BIT STRING
65 		} */
66 
67 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readRsaSubjectPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)68 static int readRsaSubjectPublicKey( INOUT STREAM *stream,
69 									INOUT CONTEXT_INFO *contextInfoPtr,
70 									OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
71 	{
72 	CRYPT_ALGO_TYPE cryptAlgo DUMMY_INIT;
73 	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
74 	int status;
75 
76 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
77 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
78 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
79 
80 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
81 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
82 
83 	/* Clear return value */
84 	*actionFlags = ACTION_PERM_NONE;
85 
86 	/* Read the SubjectPublicKeyInfo header field and parameter data if
87 	   there's any present.  We read the outer wrapper in generic form since
88 	   it may be context-specific-tagged if it's coming from a keyset (RSA
89 	   public keys is the one place where PKCS #15 keys differ from X.509
90 	   ones) or something odd from CRMF */
91 	status = readGenericHole( stream, NULL, 8 + MIN_PKCSIZE_THRESHOLD + \
92 											RSAPARAM_MIN_E, DEFAULT_TAG );
93 	if( cryptStatusOK( status ) )
94 		status = readAlgoID( stream, &cryptAlgo, ALGOID_CLASS_PKC );
95 	if( cryptStatusError( status ) )
96 		return( status );
97 	if( cryptAlgo != CRYPT_ALGO_RSA )
98 		return( CRYPT_ERROR_BADDATA );
99 
100 	/* Set the maximum permitted actions.  More restrictive permissions may
101 	   be set by higher-level code if required and in particular if the key
102 	   is a pure public key rather than merely the public portions of a
103 	   private key then the actions will be restricted at that point to
104 	   encrypt and signature-check only */
105 	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_ALL ) | \
106 				   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_ALL ) | \
107 				   MK_ACTION_PERM( MESSAGE_CTX_SIGN, ACTION_PERM_ALL ) | \
108 				   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, ACTION_PERM_ALL );
109 
110 	/* Read the BIT STRING encapsulation and the public key fields */
111 	readBitStringHole( stream, NULL, MIN_PKCSIZE_THRESHOLD, DEFAULT_TAG );
112 	readSequence( stream, NULL );
113 	status = readBignumChecked( stream, &rsaKey->rsaParam_n,
114 								RSAPARAM_MIN_N, RSAPARAM_MAX_N, NULL );
115 	if( cryptStatusOK( status ) )
116 		status = readBignum( stream, &rsaKey->rsaParam_e,
117 							 RSAPARAM_MIN_E, RSAPARAM_MAX_E,
118 							 &rsaKey->rsaParam_n );
119 	if( cryptStatusError( status ) )
120 		return( status );
121 
122 	ENSURES( sanityCheckPKCInfo( rsaKey ) );
123 
124 	return( CRYPT_OK );
125 	}
126 
127 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readDlpSubjectPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)128 static int readDlpSubjectPublicKey( INOUT STREAM *stream,
129 									INOUT CONTEXT_INFO *contextInfoPtr,
130 									OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
131 	{
132 	PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
133 	CRYPT_ALGO_TYPE cryptAlgo DUMMY_INIT;
134 	int extraLength DUMMY_INIT, status;
135 
136 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
137 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
138 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
139 
140 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
141 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
142 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
143 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
144 
145 	/* Clear return value */
146 	*actionFlags = ACTION_PERM_NONE;
147 
148 	/* Read the SubjectPublicKeyInfo header field and make sure that the DLP
149 	   parameter data is present */
150 	status = readGenericHole( stream, NULL,
151 							  8 + MIN_PKCSIZE_THRESHOLD + DLPPARAM_MIN_G + \
152 							  DLPPARAM_MIN_Q + MIN_PKCSIZE_THRESHOLD,
153 							  DEFAULT_TAG );
154 	if( cryptStatusOK( status ) )
155 		status = readAlgoIDparam( stream, &cryptAlgo, &extraLength,
156 								  ALGOID_CLASS_PKC );
157 	if( cryptStatusError( status ) )
158 		return( status );
159 	if( extraLength < MIN_PKCSIZE_THRESHOLD + DLPPARAM_MIN_G + \
160 					  DLPPARAM_MIN_Q || \
161 		extraLength > MAX_INTLENGTH_SHORT )
162 		return( CRYPT_ERROR_BADDATA );
163 	if( contextInfoPtr->capabilityInfo->cryptAlgo != cryptAlgo )
164 		return( CRYPT_ERROR_BADDATA );
165 
166 	/* Read the header and key parameters */
167 	readSequence( stream, NULL );
168 	status = readBignumChecked( stream, &dlpKey->dlpParam_p,
169 								DLPPARAM_MIN_P, DLPPARAM_MAX_P, NULL );
170 	if( cryptStatusError( status ) )
171 		return( status );
172 	if( hasReversedParams( cryptAlgo ) )
173 		{
174 		status = readBignum( stream, &dlpKey->dlpParam_g, DLPPARAM_MIN_G,
175 							 DLPPARAM_MAX_G, &dlpKey->dlpParam_p );
176 		if( cryptStatusOK( status ) )
177 			status = readBignum( stream, &dlpKey->dlpParam_q, DLPPARAM_MIN_Q,
178 								 DLPPARAM_MAX_Q, &dlpKey->dlpParam_p );
179 		}
180 	else
181 		{
182 		status = readBignum( stream, &dlpKey->dlpParam_q, DLPPARAM_MIN_Q,
183 							 DLPPARAM_MAX_Q, &dlpKey->dlpParam_p );
184 		if( cryptStatusOK( status ) )
185 			status = readBignum( stream, &dlpKey->dlpParam_g, DLPPARAM_MIN_G,
186 								 DLPPARAM_MAX_G, &dlpKey->dlpParam_p );
187 		}
188 	if( cryptStatusError( status ) )
189 		return( status );
190 
191 	/* Set the maximum permitted actions.  Because of the special-case data
192 	   formatting requirements for DLP algorithms we make the usage
193 	   internal-only.  If the key is a pure public key rather than merely
194 	   the public portions of a private key then the actions will be
195 	   restricted by higher-level code to encrypt/signature-check only */
196 	if( cryptAlgo == CRYPT_ALGO_DSA )
197 		{
198 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
199 									   ACTION_PERM_NONE_EXTERNAL ) | \
200 					   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
201 									   ACTION_PERM_NONE_EXTERNAL );
202 		}
203 	else
204 		{
205 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
206 									   ACTION_PERM_NONE_EXTERNAL ) | \
207 					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
208 									   ACTION_PERM_NONE_EXTERNAL );
209 		}
210 
211 	/* Read the BIT STRING encapsulation and the public key fields */
212 	readBitStringHole( stream, NULL, MIN_PKCSIZE_THRESHOLD, DEFAULT_TAG );
213 	status = readBignumChecked( stream, &dlpKey->dlpParam_y,
214 								DLPPARAM_MIN_Y, DLPPARAM_MAX_Y,
215 								&dlpKey->dlpParam_p );
216 	if( cryptStatusError( status ) )
217 		return( status );
218 
219 	ENSURES( sanityCheckPKCInfo( dlpKey ) );
220 
221 	return( CRYPT_OK );
222 	}
223 
224 #if defined( USE_ECDH ) || defined( USE_ECDSA )
225 
226 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readEccSubjectPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)227 static int readEccSubjectPublicKey( INOUT STREAM *stream,
228 									INOUT CONTEXT_INFO *contextInfoPtr,
229 									OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
230 	{
231 	PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
232 	CRYPT_ALGO_TYPE cryptAlgo DUMMY_INIT;
233 	CRYPT_ECCCURVE_TYPE curveType;
234 	BYTE buffer[ MAX_PKCSIZE_ECCPOINT + 8 ];
235 	int fieldSize DUMMY_INIT;
236 	int length, extraLength DUMMY_INIT, status;
237 
238 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
239 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
240 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
241 
242 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
243 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
244 
245 	/* Clear return value */
246 	*actionFlags = ACTION_PERM_NONE;
247 
248 	/* Read the SubjectPublicKeyInfo header field and make sure that the ECC
249 	   parameter data is present.  Because of the more or less arbitrary
250 	   manner in which these parameters can be represented we have to be
251 	   fairly open-ended in terms of the data size limits that we use, and
252 	   in particular for named curves the lower bound is the size of a
253 	   single OID that defines the curve */
254 	status = readGenericHole( stream, NULL,
255 							  8 + MIN_OID_SIZE + \
256 							  MIN_PKCSIZE_ECCPOINT_THRESHOLD,
257 							  DEFAULT_TAG );
258 	if( cryptStatusOK( status ) )
259 		status = readAlgoIDparam( stream, &cryptAlgo, &extraLength,
260 								  ALGOID_CLASS_PKC );
261 	if( cryptStatusError( status ) )
262 		return( status );
263 	if( extraLength < MIN_OID_SIZE || extraLength > MAX_INTLENGTH_SHORT )
264 		return( CRYPT_ERROR_BADDATA );
265 	if( contextInfoPtr->capabilityInfo->cryptAlgo != cryptAlgo )
266 		return( CRYPT_ERROR_BADDATA );
267 
268 	/* Now things get messy, since the ECC standards authors carefully
269 	   sidestepped having to make a decision about anything and instead
270 	   just created an open framework into which it's possible to drop
271 	   almost anything.  To keep things sane we require the use of named
272 	   curves (which most people seem to use) over a prime field */
273 	status = readECCOID( stream, &curveType );
274 	if( cryptStatusOK( status ) )
275 		status = getECCFieldSize( curveType, &fieldSize, FALSE );
276 	if( cryptStatusError( status ) )
277 		return( status );
278 	eccKey->curveType = curveType;
279 
280 	/* Set the maximum permitted actions.  Because of the special-case data
281 	   formatting requirements for ECC algorithms (which are a part of the
282 	   DLP algorithm family) we make the usage internal-only.  If the key is
283 	   a pure public key rather than merely the public portions of a private
284 	   key then the actions will be restricted by higher-level code to
285 	   encrypt/signature-check only */
286 	if( cryptAlgo == CRYPT_ALGO_ECDSA )
287 		{
288 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
289 									   ACTION_PERM_NONE_EXTERNAL ) | \
290 					   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
291 									   ACTION_PERM_NONE_EXTERNAL );
292 		}
293 	else
294 		{
295 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
296 									   ACTION_PERM_NONE_EXTERNAL ) | \
297 					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
298 									   ACTION_PERM_NONE_EXTERNAL );
299 		}
300 
301 	/* Read the BIT STRING encapsulation and the public key fields.  Instead
302 	   of encoding the necessary information as an obvious OID + SEQUENCE
303 	   combination for the parameters it's all stuffed into an ad-hoc BIT
304 	   STRING that we have to pick apart manually.  Note that we can't use
305 	   the ECC p value for a range check because it hasn't been set yet, all
306 	   that we have at this point is a curve ID */
307 	status = readBitStringHole( stream, &length,
308 								MIN_PKCSIZE_ECCPOINT_THRESHOLD, DEFAULT_TAG );
309 	if( cryptStatusError( status ) )
310 		return( status );
311 	if( length < MIN_PKCSIZE_ECCPOINT_THRESHOLD || \
312 		length > MAX_PKCSIZE_ECCPOINT )
313 		return( CRYPT_ERROR_BADDATA );
314 	status = sread( stream, buffer, length );
315 	if( cryptStatusError( status ) )
316 		return( status );
317 	status = importECCPoint( &eccKey->eccParam_qx, &eccKey->eccParam_qy,
318 							 buffer, length, MIN_PKCSIZE_ECC_THRESHOLD,
319 							 CRYPT_MAX_PKCSIZE_ECC, fieldSize, NULL,
320 							 KEYSIZE_CHECK_ECC );
321 	zeroise( buffer, length );
322 	if( cryptStatusError( status ) )
323 		return( status );
324 
325 	ENSURES( sanityCheckPKCInfo( eccKey ) );
326 
327 	return( CRYPT_OK );
328 	}
329 #endif /* USE_ECDH || USE_ECDSA */
330 #endif /* USE_INT_ASN1 */
331 
332 /****************************************************************************
333 *																			*
334 *								Read SSH Public Keys						*
335 *																			*
336 ****************************************************************************/
337 
338 #ifdef USE_SSH
339 
340 /* Read SSHv2 public keys:
341 
342    RSA/DSA:
343 
344 	string		[ server key/certificate ]
345 		string	"ssh-rsa"	"ssh-dss"
346 		mpint	e			p
347 		mpint	n			q
348 		mpint				g
349 		mpint				y
350 
351    ECDSA:
352 
353 	string		[ server key/certificate ]
354 		string	"ecdsa-sha2-*"
355 		string	"*"				-- The "*" portion from the above field
356 		string	Q */
357 
358 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readSshRsaPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)359 static int readSshRsaPublicKey( INOUT STREAM *stream,
360 								INOUT CONTEXT_INFO *contextInfoPtr,
361 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
362 	{
363 	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
364 	char buffer[ 16 + 8 ];
365 	int length, status;
366 
367 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
368 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
369 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
370 
371 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
372 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
373 
374 	/* Clear return value */
375 	*actionFlags = ACTION_PERM_NONE;
376 
377 	/* Read the wrapper and make sure that it's OK */
378 	readUint32( stream );
379 	status = readString32( stream, buffer, 7, &length );
380 	if( cryptStatusError( status ) )
381 		return( status );
382 	if( length != 7 || memcmp( buffer, "ssh-rsa", 7 ) )
383 		return( CRYPT_ERROR_BADDATA );
384 
385 	/* Set the maximum permitted actions.  SSH keys are only used internally
386 	   so we restrict the usage to internal-only */
387 	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
388 								   ACTION_PERM_NONE_EXTERNAL );
389 
390 	/* Read the SSH public key information */
391 	status = readBignumInteger32( stream, &rsaKey->rsaParam_e,
392 								  RSAPARAM_MIN_E, RSAPARAM_MAX_E,
393 								  NULL );
394 	if( cryptStatusOK( status ) )
395 		status = readBignumInteger32Checked( stream, &rsaKey->rsaParam_n,
396 											 RSAPARAM_MIN_N, RSAPARAM_MAX_N );
397 	if( cryptStatusError( status ) )
398 		return( status );
399 
400 	ENSURES( sanityCheckPKCInfo( rsaKey ) );
401 
402 	return( CRYPT_OK );
403 	}
404 
405 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readSshDlpPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)406 static int readSshDlpPublicKey( INOUT STREAM *stream,
407 								INOUT CONTEXT_INFO *contextInfoPtr,
408 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
409 	{
410 	PKC_INFO *dsaKey = contextInfoPtr->ctxPKC;
411 	const BOOLEAN isDH = \
412 			( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );
413 	char buffer[ 16 + 8 ];
414 	int length, status;
415 
416 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
417 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
418 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
419 
420 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
421 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
422 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA ) );
423 
424 	/* Clear return value */
425 	*actionFlags = ACTION_PERM_NONE;
426 
427 	/* Read the wrapper and make sure that it's OK.  SSHv2 uses PKCS #3
428 	   rather than X9.42-style DH keys so we have to treat this algorithm
429 	   type specially */
430 	readUint32( stream );
431 	if( isDH )
432 		{
433 		status = readString32( stream, buffer, 6, &length );
434 		if( cryptStatusError( status ) )
435 			return( status );
436 		if( length != 6 || memcmp( buffer, "ssh-dh", 6 ) )
437 			return( CRYPT_ERROR_BADDATA );
438 
439 		/* Set the maximum permitted actions.  SSH keys are only used
440 		   internally so we restrict the usage to internal-only.  Since DH
441 		   keys can be both public and private keys we allow both usage
442 		   types even though technically it's a public key */
443 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
444 									   ACTION_PERM_NONE_EXTERNAL ) | \
445 					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
446 									   ACTION_PERM_NONE_EXTERNAL );
447 
448 		/* Read the SSH public key information */
449 		status = readBignumInteger32Checked( stream, &dsaKey->dlpParam_p,
450 											 DLPPARAM_MIN_P, DLPPARAM_MAX_P );
451 		if( cryptStatusOK( status ) )
452 			status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
453 										  DLPPARAM_MIN_G, DLPPARAM_MAX_G,
454 										  &dsaKey->dlpParam_p );
455 		return( status );
456 		}
457 
458 	/* It's a standard DLP key, read the wrapper and make sure that it's
459 	   OK */
460 	status = readString32( stream, buffer, 7, &length );
461 	if( cryptStatusError( status ) )
462 		return( status );
463 	if( length != 7 || memcmp( buffer, "ssh-dss", 7 ) )
464 		return( CRYPT_ERROR_BADDATA );
465 
466 	/* Set the maximum permitted actions.  SSH keys are only used internally
467 	   so we restrict the usage to internal-only */
468 	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
469 								   ACTION_PERM_NONE_EXTERNAL );
470 
471 	/* Read the SSH public key information */
472 	status = readBignumInteger32Checked( stream, &dsaKey->dlpParam_p,
473 										 DLPPARAM_MIN_P, DLPPARAM_MAX_P );
474 	if( cryptStatusOK( status ) )
475 		status = readBignumInteger32( stream, &dsaKey->dlpParam_q,
476 									  DLPPARAM_MIN_Q, DLPPARAM_MAX_Q,
477 									  &dsaKey->dlpParam_p );
478 	if( cryptStatusOK( status ) )
479 		status = readBignumInteger32( stream, &dsaKey->dlpParam_g,
480 									  DLPPARAM_MIN_G, DLPPARAM_MAX_G,
481 									  &dsaKey->dlpParam_p );
482 	if( cryptStatusOK( status ) && !isDH )
483 		status = readBignumInteger32( stream, &dsaKey->dlpParam_y,
484 									  DLPPARAM_MIN_Y, DLPPARAM_MAX_Y,
485 									  &dsaKey->dlpParam_p );
486 	if( cryptStatusError( status ) )
487 		return( status );
488 
489 	ENSURES( sanityCheckPKCInfo( dsaKey ) );
490 
491 	return( CRYPT_OK );
492 	}
493 
494 #if defined( USE_ECDH ) || defined( USE_ECDSA )
495 
496 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readSshEccPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)497 static int readSshEccPublicKey( INOUT STREAM *stream,
498 								INOUT CONTEXT_INFO *contextInfoPtr,
499 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
500 	{
501 	PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
502 	const BOOLEAN isECDH = \
503 			( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH );
504 	BYTE buffer[ MAX_PKCSIZE_ECCPOINT + 8 ];
505 	int length, fieldSize, status;
506 
507 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
508 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
509 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
510 
511 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
512 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );
513 
514 	/* Clear return value */
515 	*actionFlags = ACTION_PERM_NONE;
516 
517 	/* Set the maximum permitted actions.  SSH keys are only used
518 	   internally so we restrict the usage to internal-only.  Since ECDH
519 	   keys can be both public and private keys we allow both usage
520 	   types even though technically it's a public key */
521 	if( isECDH )
522 		{
523 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
524 									   ACTION_PERM_NONE_EXTERNAL ) | \
525 					   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
526 									   ACTION_PERM_NONE_EXTERNAL );
527 		}
528 	else
529 		{
530 		*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
531 									   ACTION_PERM_NONE_EXTERNAL );
532 		}
533 
534 	/* Read the wrapper and make sure that it's OK.  The key parameter
535 	   information is repeated twice, so for the overall wrapper we only
536 	   check for the ECDH/ECDSA algorithm indication and get the parameter
537 	   information from the second version, which contains only the
538 	   parameter string */
539 	readUint32( stream );
540 	status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
541 	if( cryptStatusError( status ) )
542 		return( status );
543 	if( length < 18 )		/* "ecdh-sha2-nistXXXX" */
544 		return( CRYPT_ERROR_BADDATA );
545 	if( isECDH )
546 		{
547 		if( memcmp( buffer, "ecdh-sha2-", 10 ) )
548 			return( CRYPT_ERROR_BADDATA );
549 		}
550 	else
551 		{
552 		if( memcmp( buffer, "ecdsa-sha2-", 11 ) )
553 			return( CRYPT_ERROR_BADDATA );
554 		}
555 
556 	/* Read and process the parameter information.  At this point we know
557 	   that we've got valid ECC key data, so if we find anything unexpected
558 	   we report it as an unavailable ECC field size rather than bad data */
559 	status = readString32( stream, buffer, CRYPT_MAX_TEXTSIZE, &length );
560 	if( cryptStatusError( status ) )
561 		return( status );
562 	if( length != 8 )		/* "nistXXXX" */
563 		return( CRYPT_ERROR_NOTAVAIL );
564 	if( !memcmp( buffer, "nistp256", 8 ) )
565 		eccKey->curveType = CRYPT_ECCCURVE_P256;
566 	else
567 		{
568 		if( !memcmp( buffer, "nistp384", 8 ) )
569 			eccKey->curveType = CRYPT_ECCCURVE_P384;
570 		else
571 			{
572 			if( !memcmp( buffer, "nistp521", 8 ) )
573 				eccKey->curveType = CRYPT_ECCCURVE_P521;
574 			else
575 				return( CRYPT_ERROR_NOTAVAIL );
576 			}
577 		}
578 	status = getECCFieldSize( eccKey->curveType, &fieldSize, FALSE );
579 	if( cryptStatusError( status ) )
580 		return( status );
581 
582 	/* Read the ECC public key.  See the comments in
583 	   readEccSubjectPublicKey() for why the checks are done the way they
584 	   are */
585 	status = readString32( stream, buffer, MAX_PKCSIZE_ECCPOINT, &length );
586 	if( cryptStatusError( status ) )
587 		return( status );
588 	if( length < MIN_PKCSIZE_ECCPOINT_THRESHOLD || \
589 		length > MAX_PKCSIZE_ECCPOINT )
590 		return( CRYPT_ERROR_BADDATA );
591 	status = importECCPoint( &eccKey->eccParam_qx, &eccKey->eccParam_qy,
592 							 buffer, length, MIN_PKCSIZE_ECC_THRESHOLD,
593 							 CRYPT_MAX_PKCSIZE_ECC, fieldSize, NULL,
594 							 KEYSIZE_CHECK_ECC );
595 	zeroise( buffer, length );
596 	if( cryptStatusError( status ) )
597 		return( status );
598 
599 	ENSURES( sanityCheckPKCInfo( eccKey ) );
600 
601 	return( CRYPT_OK );
602 	}
603 #endif /* USE_ECDH || USE_ECDSA */
604 #endif /* USE_SSH */
605 
606 /****************************************************************************
607 *																			*
608 *								Read SSL Public Keys						*
609 *																			*
610 ****************************************************************************/
611 
612 #ifdef USE_SSL
613 
614 /* Read SSL public keys:
615 
616 	DH:
617 		uint16		dh_pLen
618 		byte[]		dh_p
619 		uint16		dh_gLen
620 		byte[]		dh_g
621 	  [	uint16		dh_YsLen ]
622 	  [	byte[]		dh_Ys	 ]
623 
624 	ECDH:
625 		byte		curveType
626 		uint16		namedCurve
627 	  [	uint8		ecPointLen	-- NB uint8 not uint16 ]
628 	  [	byte[]		ecPoint ]
629 
630    The DH y value is nominally attached to the DH p and g values but isn't
631    processed at this level since this is a pure PKCS #3 DH key and not a
632    generic DLP key.  The same holds for the ECDH Q value */
633 
634 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readSslDlpPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)635 static int readSslDlpPublicKey( INOUT STREAM *stream,
636 								INOUT CONTEXT_INFO *contextInfoPtr,
637 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
638 	{
639 	PKC_INFO *dhKey = contextInfoPtr->ctxPKC;
640 	int status;
641 
642 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
643 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
644 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
645 
646 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
647 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH );
648 
649 	/* Clear return value */
650 	*actionFlags = ACTION_PERM_NONE;
651 
652 	/* Set the maximum permitted actions.  SSL keys are only used
653 	   internally so we restrict the usage to internal-only.  Since DH
654 	   keys can be both public and private keys we allow both usage
655 	   types even though technically it's a public key */
656 	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
657 								   ACTION_PERM_NONE_EXTERNAL ) | \
658 				   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
659 								   ACTION_PERM_NONE_EXTERNAL );
660 
661 	/* Read the SSL public key information */
662 	status = readBignumInteger16UChecked( stream, &dhKey->dlpParam_p,
663 										  DLPPARAM_MIN_P, DLPPARAM_MAX_P );
664 	if( cryptStatusOK( status ) )
665 		status = readBignumInteger16U( stream, &dhKey->dlpParam_g,
666 									   DLPPARAM_MIN_G, DLPPARAM_MAX_G,
667 									   &dhKey->dlpParam_p );
668 	if( cryptStatusError( status ) )
669 		return( status );
670 
671 	ENSURES( sanityCheckPKCInfo( dhKey ) );
672 
673 	return( CRYPT_OK );
674 	}
675 
676 #if defined( USE_ECDH )
677 
678 static const MAP_TABLE sslCurveInfo[] = {
679 	{ /* TLS_CURVE_SECP256R1 */ 23, CRYPT_ECCCURVE_P256 },
680 	{ /* TLS_CURVE_SECP384R1 */ 24, CRYPT_ECCCURVE_P384 },
681 	{ /* TLS_CURVE_SECP521R1 */ 25, CRYPT_ECCCURVE_P521 },
682 	{ /* TLS_CURVE_BRAINPOOLP256R1 */ 26, CRYPT_ECCCURVE_BRAINPOOL_P256 },
683 	{ /* TLS_CURVE_BRAINPOOLP384R1 */ 27, CRYPT_ECCCURVE_BRAINPOOL_P384 },
684 	{ /* TLS_CURVE_BRAINPOOLP512R1 */ 28, CRYPT_ECCCURVE_BRAINPOOL_P512 },
685 	{ CRYPT_ERROR, 0 },
686 		{ CRYPT_ERROR, 0 }
687 	};
688 
689 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
getEccSslInfoTbl(OUT const MAP_TABLE ** sslInfoTblPtr,OUT_INT_Z int * noSslInfoTblEntries)690 static int getEccSslInfoTbl( OUT const MAP_TABLE **sslInfoTblPtr,
691 							 OUT_INT_Z int *noSslInfoTblEntries )
692 	{
693 	assert( isReadPtr( sslInfoTblPtr, sizeof( MAP_TABLE * ) ) );
694 	assert( isWritePtr( noSslInfoTblEntries, sizeof( int ) ) );
695 
696 	*sslInfoTblPtr = sslCurveInfo;
697 	*noSslInfoTblEntries = FAILSAFE_ARRAYSIZE( sslCurveInfo, MAP_TABLE );
698 
699 	return( CRYPT_OK );
700 	}
701 
702 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readSslEccPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)703 static int readSslEccPublicKey( INOUT STREAM *stream,
704 								INOUT CONTEXT_INFO *contextInfoPtr,
705 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
706 	{
707 	PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
708 	const MAP_TABLE *sslCurveInfoPtr;
709 	int value, curveID, sslCurveInfoNoEntries, status;
710 
711 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
712 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
713 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
714 
715 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
716 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH );
717 
718 	/* Clear return value */
719 	*actionFlags = ACTION_PERM_NONE;
720 
721 	/* Set the maximum permitted actions.  SSL keys are only used
722 	   internally so we restrict the usage to internal-only.  Since ECDH
723 	   keys can be both public and private keys we allow both usage
724 	   types even though technically it's a public key */
725 	*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
726 								   ACTION_PERM_NONE_EXTERNAL ) | \
727 				   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
728 								   ACTION_PERM_NONE_EXTERNAL );
729 
730 	/* Read the SSL public key information */
731 	status = value = sgetc( stream );
732 	if( cryptStatusError( status ) )
733 		return( status );
734 	if( value != 0x03 )		/* NamedCurve */
735 		return( CRYPT_ERROR_BADDATA );
736 	status = value = readUint16( stream );
737 	if( cryptStatusError( status ) )
738 		return( status );
739 	if( value < 19 || value > 28 )
740 		return( CRYPT_ERROR_NOTAVAIL );
741 
742 	/* Look up the curve ID based on the SSL NamedCurve ID */
743 	status = getEccSslInfoTbl( &sslCurveInfoPtr, &sslCurveInfoNoEntries );
744 	if( cryptStatusError( status ) )
745 		return( status );
746 	status = mapValue( value, &curveID, sslCurveInfoPtr,
747 					   sslCurveInfoNoEntries );
748 	if( cryptStatusError( status ) )
749 		return( status );
750 	eccKey->curveType = curveID;
751 
752 	ENSURES( sanityCheckPKCInfo( eccKey ) );
753 
754 	return( CRYPT_OK );
755 	}
756 #endif /* USE_ECDH */
757 #endif /* USE_SSL */
758 
759 /****************************************************************************
760 *																			*
761 *								Read PGP Public Keys						*
762 *																			*
763 ****************************************************************************/
764 
765 #ifdef USE_PGP
766 
767 /* Read PGP public keys:
768 
769 	byte		version
770 	uint32		creationTime
771 	[ uint16	validity - version 2 or 3 only ]
772 	byte		RSA		DSA		Elgamal		ECDH/ECDSA
773 	mpi			n		p		p			qx/qy
774 	mpi			e		q		g
775 	mpi					g		y
776 	mpi					y */
777 
778 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPgpHeader(INOUT STREAM * stream,OUT time_t * pgpCreationTime,const BOOLEAN openPgpOnly)779 static int readPgpHeader( INOUT STREAM *stream,
780 						  OUT time_t *pgpCreationTime,
781 						  const BOOLEAN openPgpOnly )
782 	{
783 	int version, value, status;
784 
785 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
786 	assert( isWritePtr( pgpCreationTime, sizeof( time_t ) ) );
787 
788 	/* Clear return value */
789 	*pgpCreationTime = 0;
790 
791 	/* Read the PGP version info */
792 	status = version = sgetc( stream );
793 	if( cryptStatusError( status ) )
794 		return( status );
795 	if( openPgpOnly )
796 		{
797 		if( version != PGP_VERSION_OPENPGP )
798 			return( CRYPT_ERROR_BADDATA );
799 		}
800 	else
801 		{
802 		if( version != PGP_VERSION_2 && version != PGP_VERSION_3 && \
803 			version != PGP_VERSION_OPENPGP )
804 			return( CRYPT_ERROR_BADDATA );
805 		}
806 
807 	/* Read the creation time.  In theory we should do this with
808 	   readUint32Time(), however some keys coming from non-PGP sources can
809 	   have a creation time of zero which would result in the value being
810 	   rejected by the time read.  Because of this we have to read the value
811 	   as a standard 32-bit int and the perform the range check that's
812 	   otherwise performed by readUint32Time(), with an exception for a time
813 	   value of 0 */
814 	status = value = readUint32( stream );
815 	if( cryptStatusError( status ) )
816 		return( status );
817 	if( ( value < MIN_STORED_TIME_VALUE && value != 0 ) || \
818 		value >= 0x7FFFFFFFL )
819 		return( CRYPT_ERROR_BADDATA );
820 	*pgpCreationTime = ( time_t ) value;
821 
822 	/* Skip the validity time if it's present */
823 	if( version == PGP_VERSION_2 || version == PGP_VERSION_3 )
824 		return( sSkip( stream, 2, 2 ) );
825 
826 	return( CRYPT_OK );
827 	}
828 
829 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readPgpRsaPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)830 static int readPgpRsaPublicKey( INOUT STREAM *stream,
831 								INOUT CONTEXT_INFO *contextInfoPtr,
832 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
833 	{
834 	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
835 	int value, status;
836 
837 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
838 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
839 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
840 
841 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
842 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
843 
844 	/* Clear return value */
845 	*actionFlags = ACTION_PERM_NONE;
846 
847 	/* Read the header info */
848 	status = readPgpHeader( stream, &rsaKey->pgpCreationTime, FALSE );
849 	if( cryptStatusError( status ) )
850 		return( status );
851 
852 	/* Set the maximum permitted actions.  If there are no restrictions we
853 	   allow external usage, if the keys are encryption-only or signature-
854 	   only we make the usage internal-only because of RSA's signature/
855 	   encryption duality.  If the key is a pure public key rather than
856 	   merely the public portions of a private key then the actions will be
857 	   restricted by higher-level code to encrypt/signature-check only */
858 	status = value = sgetc( stream );
859 	if( cryptStatusError( status ) )
860 		return( status );
861 	switch( value )
862 		{
863 		case PGP_ALGO_RSA:
864 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
865 										   ACTION_PERM_ALL ) | \
866 						   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
867 										   ACTION_PERM_ALL ) | \
868 						   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
869 										   ACTION_PERM_ALL ) | \
870 						   MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
871 										   ACTION_PERM_ALL );
872 			break;
873 
874 		case PGP_ALGO_RSA_ENCRYPT:
875 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
876 										   ACTION_PERM_NONE_EXTERNAL ) | \
877 						   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
878 										   ACTION_PERM_NONE_EXTERNAL );
879 			break;
880 
881 		case PGP_ALGO_RSA_SIGN:
882 			*actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
883 											ACTION_PERM_NONE_EXTERNAL ) | \
884 							MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
885 											ACTION_PERM_NONE_EXTERNAL );
886 			break;
887 
888 		default:
889 			return( CRYPT_ERROR_BADDATA );
890 		}
891 
892 	/* Read the PGP public key information */
893 	status = readBignumInteger16UbitsChecked( stream, &rsaKey->rsaParam_n,
894 											  bytesToBits( RSAPARAM_MIN_N ),
895 											  bytesToBits( RSAPARAM_MAX_N ) );
896 	if( cryptStatusOK( status ) )
897 		status = readBignumInteger16Ubits( stream, &rsaKey->rsaParam_e,
898 										   bytesToBits( RSAPARAM_MIN_E ),
899 										   bytesToBits( RSAPARAM_MAX_E ),
900 										   &rsaKey->rsaParam_n );
901 	if( cryptStatusError( status ) )
902 		return( status );
903 
904 	ENSURES( sanityCheckPKCInfo( rsaKey ) );
905 
906 	return( CRYPT_OK );
907 	}
908 
909 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readPgpDlpPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)910 static int readPgpDlpPublicKey( INOUT STREAM *stream,
911 								INOUT CONTEXT_INFO *contextInfoPtr,
912 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
913 	{
914 	PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
915 	int value, status;
916 
917 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
918 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
919 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
920 
921 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
922 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
923 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
924 
925 	/* Clear return value */
926 	*actionFlags = ACTION_PERM_NONE;
927 
928 	/* Read the header info */
929 	status = readPgpHeader( stream, &dlpKey->pgpCreationTime, TRUE );
930 	if( cryptStatusError( status ) )
931 		return( status );
932 
933 	/* Set the maximum permitted actions.  Because of the special-case data
934 	   formatting requirements for DLP algorithms we make the usage
935 	   internal-only.  If the key is a pure public key rather than merely
936 	   the public portions of a private key then the actions will be
937 	   restricted by higher-level code to encrypt/signature-check only  */
938 	status = value = sgetc( stream );
939 	if( cryptStatusError( status ) )
940 		return( status );
941 	switch( value )
942 		{
943 		case PGP_ALGO_DSA:
944 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
945 										   ACTION_PERM_NONE_EXTERNAL ) | \
946 						   MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
947 										   ACTION_PERM_NONE_EXTERNAL );
948 			break;
949 
950 		case PGP_ALGO_ELGAMAL:
951 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
952 										   ACTION_PERM_NONE_EXTERNAL ) | \
953 						   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
954 										   ACTION_PERM_NONE_EXTERNAL );
955 			break;
956 
957 		default:
958 			return( CRYPT_ERROR_BADDATA );
959 		}
960 
961 	/* Read the PGP public key information */
962 	status = readBignumInteger16UbitsChecked( stream, &dlpKey->dlpParam_p,
963 											  bytesToBits( DLPPARAM_MIN_P ),
964 											  bytesToBits( DLPPARAM_MAX_P ) );
965 	if( cryptStatusOK( status ) && value == PGP_ALGO_DSA )
966 		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_q,
967 										   bytesToBits( DLPPARAM_MIN_Q ),
968 										   bytesToBits( DLPPARAM_MAX_Q ),
969 										   &dlpKey->dlpParam_p );
970 	if( cryptStatusOK( status ) )
971 		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_g,
972 										   bytesToBits( DLPPARAM_MIN_G ),
973 										   bytesToBits( DLPPARAM_MAX_G ),
974 										   &dlpKey->dlpParam_p );
975 	if( cryptStatusOK( status ) )
976 		status = readBignumInteger16Ubits( stream, &dlpKey->dlpParam_y,
977 										   bytesToBits( DLPPARAM_MIN_Y ),
978 										   bytesToBits( DLPPARAM_MAX_Y ),
979 										   &dlpKey->dlpParam_p );
980 	if( cryptStatusError( status ) )
981 		return( status );
982 
983 	ENSURES( sanityCheckPKCInfo( dlpKey ) );
984 
985 	return( CRYPT_OK );
986 	}
987 
988 #if defined( USE_ECDH ) || defined( USE_ECDSA )
989 
990 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
readPgpEccPublicKey(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,OUT_FLAGS_Z (ACTION_PERM)int * actionFlags)991 static int readPgpEccPublicKey( INOUT STREAM *stream,
992 								INOUT CONTEXT_INFO *contextInfoPtr,
993 								OUT_FLAGS_Z( ACTION_PERM ) int *actionFlags )
994 	{
995 	CRYPT_ECCCURVE_TYPE curveType;
996 	PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
997 	STREAM oidStream;
998 	BYTE oidBuffer[ 2 + MAX_OID_SIZE + 8 ];
999 	int value, length, status;
1000 
1001 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1002 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1003 	assert( isWritePtr( actionFlags, sizeof( int ) ) );
1004 
1005 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1006 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA || \
1007 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH ) );
1008 
1009 	/* Clear return value */
1010 	*actionFlags = ACTION_PERM_NONE;
1011 
1012 	/* Read the header info */
1013 	status = readPgpHeader( stream, &eccKey->pgpCreationTime, TRUE );
1014 	if( cryptStatusError( status ) )
1015 		return( status );
1016 
1017 	/* Set the maximum permitted actions.  Because of the special-case data
1018 	   formatting requirements for ECC algorithms (which are a part of the
1019 	   DLP algorithm family) we make the usage internal-only.  If the key is
1020 	   a pure public key rather than merely the public portions of a private
1021 	   key then the actions will be restricted by higher-level code to
1022 	   encrypt/signature-check only */
1023 	status = value = sgetc( stream );
1024 	if( cryptStatusError( status ) )
1025 		return( status );
1026 	switch( value )
1027 		{
1028 		case PGP_ALGO_ECDH:
1029 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
1030 										   ACTION_PERM_NONE_EXTERNAL ) | \
1031 						   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
1032 										   ACTION_PERM_NONE_EXTERNAL );
1033 			break;
1034 
1035 		case PGP_ALGO_ECDSA:
1036 			*actionFlags = MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
1037 										   ACTION_PERM_NONE_EXTERNAL ) | \
1038 						   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
1039 										   ACTION_PERM_NONE_EXTERNAL );
1040 			break;
1041 
1042 		default:
1043 			return( CRYPT_ERROR_BADDATA );
1044 		}
1045 
1046 	/* Read the ECC OID, preceded by a length byte.  For no known reason
1047 	   (probably a coding error that was made part of the spec), the PGP
1048 	   format omits the first two bytes of the OID, so we have to read the
1049 	   value into an intermediate buffer and recreate the full OID from
1050 	   it */
1051 	status = length = sgetc( stream );
1052 	if( cryptStatusError( status ) )
1053 		return( status );
1054 	if( length < MIN_OID_SIZE || length >= MAX_OID_SIZE )
1055 		return( CRYPT_ERROR_BADDATA );
1056 	oidBuffer[ 0 ] = 0x06;		/* OID tag */
1057 	oidBuffer[ 1 ] = intToByte( length );
1058 	status = sread( stream, oidBuffer + 2, length );
1059 	if( cryptStatusError( status ) )
1060 		return( status );
1061 	sMemConnect( &oidStream, oidBuffer, 2 + length );
1062 	status = readECCOID( &oidStream, &curveType );
1063 	sMemDisconnect( &oidStream );
1064 	if( cryptStatusError( status ) )
1065 		return( status );
1066 	eccKey->curveType = curveType;
1067 
1068 	ENSURES( sanityCheckPKCInfo( eccKey ) );
1069 
1070 	/* We don't do PGP ECC yet since there's barely any use of it to test
1071 	   against */
1072 	return( CRYPT_ERROR_BADDATA );
1073 	}
1074 #endif /* USE_ECDH || USE_ECDSA */
1075 #endif /* USE_PGP */
1076 
1077 /****************************************************************************
1078 *																			*
1079 *							Public-Key Read Interface						*
1080 *																			*
1081 ****************************************************************************/
1082 
1083 /* Umbrella public-key read functions */
1084 
1085 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
completePubkeyRead(INOUT CONTEXT_INFO * contextInfoPtr,IN_FLAGS (ACTION_PERM)const int actionFlags)1086 static int completePubkeyRead( INOUT CONTEXT_INFO *contextInfoPtr,
1087 							   IN_FLAGS( ACTION_PERM ) const int actionFlags )
1088 	{
1089 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1090 
1091 	REQUIRES( actionFlags > ACTION_PERM_FLAG_NONE && \
1092 			  actionFlags < ACTION_PERM_FLAG_MAX );
1093 
1094 	/* If it's statically-initialised context data used in the self-test
1095 	   then there's no corresponding cryptlib object and we're done */
1096 	if( contextInfoPtr->flags & CONTEXT_FLAG_STATICCONTEXT )
1097 		return( CRYPT_OK );
1098 
1099 	/* Set the action permissions for the context */
1100 	return( krnlSendMessage( contextInfoPtr->objectHandle,
1101 							 IMESSAGE_SETATTRIBUTE,
1102 							 ( MESSAGE_CAST ) &actionFlags,
1103 							 CRYPT_IATTRIBUTE_ACTIONPERMS ) );
1104 	}
1105 
1106 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPublicKeyRsaFunction(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (KEYFORMAT)const KEYFORMAT_TYPE formatType)1107 static int readPublicKeyRsaFunction( INOUT STREAM *stream,
1108 									 INOUT CONTEXT_INFO *contextInfoPtr,
1109 									 IN_ENUM( KEYFORMAT )  \
1110 										const KEYFORMAT_TYPE formatType )
1111 	{
1112 	int actionFlags, status;
1113 
1114 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1115 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1116 
1117 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1118 			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );
1119 	REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1120 
1121 	switch( formatType )
1122 		{
1123 #ifdef USE_INT_ASN1
1124 		case KEYFORMAT_CERT:
1125 			status = readRsaSubjectPublicKey( stream, contextInfoPtr,
1126 											  &actionFlags );
1127 			break;
1128 #endif /* USE_INT_ASN1 */
1129 
1130 #ifdef USE_SSH
1131 		case KEYFORMAT_SSH:
1132 			status = readSshRsaPublicKey( stream, contextInfoPtr,
1133 										  &actionFlags );
1134 			break;
1135 #endif /* USE_SSH */
1136 
1137 #ifdef USE_PGP
1138 		case KEYFORMAT_PGP:
1139 			status = readPgpRsaPublicKey( stream, contextInfoPtr,
1140 										  &actionFlags );
1141 			break;
1142 #endif /* USE_PGP */
1143 
1144 		default:
1145 			retIntError();
1146 		}
1147 	if( cryptStatusError( status ) )
1148 		return( status );
1149 	return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1150 	}
1151 
1152 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPublicKeyDlpFunction(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (KEYFORMAT)const KEYFORMAT_TYPE formatType)1153 static int readPublicKeyDlpFunction( INOUT STREAM *stream,
1154 									 INOUT CONTEXT_INFO *contextInfoPtr,
1155 									 IN_ENUM( KEYFORMAT )  \
1156 										const KEYFORMAT_TYPE formatType )
1157 	{
1158 	int actionFlags, status;
1159 
1160 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1161 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1162 
1163 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1164 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
1165 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
1166 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );
1167 	REQUIRES( formatType > KEYFORMAT_NONE && formatType < KEYFORMAT_LAST );
1168 
1169 	switch( formatType )
1170 		{
1171 #ifdef USE_INT_ASN1
1172 		case KEYFORMAT_CERT:
1173 			status = readDlpSubjectPublicKey( stream, contextInfoPtr,
1174 											  &actionFlags );
1175 			break;
1176 #endif /* USE_INT_ASN1 */
1177 
1178 #ifdef USE_SSH
1179 		case KEYFORMAT_SSH:
1180 			status = readSshDlpPublicKey( stream, contextInfoPtr,
1181 										  &actionFlags );
1182 			break;
1183 #endif /* USE_SSH */
1184 
1185 #ifdef USE_SSL
1186 		case KEYFORMAT_SSL:
1187 			status = readSslDlpPublicKey( stream, contextInfoPtr,
1188 										  &actionFlags );
1189 			break;
1190 #endif /* USE_SSL */
1191 
1192 #ifdef USE_PGP
1193 		case KEYFORMAT_PGP:
1194 			status = readPgpDlpPublicKey( stream, contextInfoPtr,
1195 										  &actionFlags );
1196 			break;
1197 #endif /* USE_PGP */
1198 
1199 		default:
1200 			retIntError();
1201 		}
1202 	if( cryptStatusError( status ) )
1203 		return( status );
1204 	return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1205 	}
1206 
1207 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1208 
1209 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPublicKeyEccFunction(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (KEYFORMAT)const KEYFORMAT_TYPE formatType)1210 static int readPublicKeyEccFunction( INOUT STREAM *stream,
1211 									 INOUT CONTEXT_INFO *contextInfoPtr,
1212 									 IN_ENUM( KEYFORMAT )  \
1213 										const KEYFORMAT_TYPE formatType )
1214 	{
1215 	int actionFlags, status;
1216 
1217 	assert( isWritePtr( stream, sizeof( STREAM ) ) );
1218 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1219 
1220 	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
1221 			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA || \
1222 				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDH ) );
1223 	REQUIRES( formatType == KEYFORMAT_CERT || formatType == KEYFORMAT_SSL || \
1224 			  formatType == KEYFORMAT_SSH || formatType == KEYFORMAT_PGP );
1225 
1226 	switch( formatType )
1227 		{
1228 #ifdef USE_INT_ASN1
1229 		case KEYFORMAT_CERT:
1230 			status = readEccSubjectPublicKey( stream, contextInfoPtr,
1231 											  &actionFlags );
1232 			break;
1233 #endif /* USE_INT_ASN1 */
1234 
1235 		/* TLS only uses ECDH (the ECDSA key data is conveyed in a
1236 		   certificate) so we only enable the TLS format if ECDH is defined
1237 		   rather than ECDH or ECDSA */
1238 #if defined( USE_SSL ) && defined( USE_ECDH )
1239 		case KEYFORMAT_SSL:
1240 			status = readSslEccPublicKey( stream, contextInfoPtr,
1241 										  &actionFlags );
1242 			break;
1243 #endif /* USE_SSL && USE_ECDH */
1244 
1245 #ifdef USE_SSH
1246 		case KEYFORMAT_SSH:
1247 			status = readSshEccPublicKey( stream, contextInfoPtr,
1248 										  &actionFlags );
1249 			break;
1250 #endif /* USE_SSH */
1251 
1252 #ifdef USE_PGP
1253 		case KEYFORMAT_PGP:
1254 			status = readPgpEccPublicKey( stream, contextInfoPtr,
1255 										  &actionFlags );
1256 			break;
1257 #endif /* USE_SSH */
1258 
1259 		default:
1260 			retIntError();
1261 		}
1262 	if( cryptStatusError( status ) )
1263 		return( status );
1264 	return( completePubkeyRead( contextInfoPtr, actionFlags ) );
1265 	}
1266 #endif /* USE_ECDH || USE_ECDSA */
1267 
1268 /****************************************************************************
1269 *																			*
1270 *								Read DL Values								*
1271 *																			*
1272 ****************************************************************************/
1273 
1274 /* Unlike the simpler RSA PKC, DL-based PKCs produce a pair of values that
1275    need to be encoded as structured data.  The following two functions
1276    decode the encoded forms from various formats.  SSH assumes that DLP
1277    values are two fixed-size blocks of 20 bytes so we can't use the normal
1278    read/write routines to handle these values */
1279 
1280 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 5 ) ) \
IN_BUFFER(bufSize)1281 static int decodeDLValuesFunction( IN_BUFFER( bufSize ) const BYTE *buffer,
1282 								   IN_LENGTH_SHORT_MIN( 32 ) const int bufSize,
1283 								   INOUT BIGNUM *value1,
1284 								   INOUT BIGNUM *value2,
1285 								   const BIGNUM *maxRange,
1286 								   IN_ENUM( CRYPT_FORMAT )  \
1287 										const CRYPT_FORMAT_TYPE formatType )
1288 	{
1289 	STREAM stream;
1290 	int status;
1291 
1292 	assert( isReadPtr( buffer, bufSize ) );
1293 	assert( isWritePtr( value1, sizeof( BIGNUM ) ) );
1294 	assert( isWritePtr( value2, sizeof( BIGNUM ) ) );
1295 	assert( isReadPtr( maxRange, sizeof( BIGNUM ) ) );
1296 
1297 	REQUIRES( bufSize >= 32 && bufSize < MAX_INTLENGTH_SHORT );
1298 	REQUIRES( formatType > CRYPT_FORMAT_NONE && \
1299 			  formatType < CRYPT_FORMAT_LAST );
1300 
1301 	/* Clear return values */
1302 	BN_clear( value1 );
1303 	BN_clear( value2 );
1304 
1305 	sMemConnect( &stream, buffer, bufSize );
1306 
1307 	/* Read the DL components from the buffer and make sure that they're
1308 	   valid, i.e. that they're in the range [1...maxRange - 1] (the lower
1309 	   bound is actually DLPPARAM_MIN_SIG_x and not 1, which is > 100 bits).
1310 	   Although nominally intended for DLP algorithms the DLPPARAM_MIN_SIG_x
1311 	   values also work for ECC ones since they're also in the DLP family */
1312 	switch( formatType )
1313 		{
1314 #ifdef USE_INT_ASN1
1315 		case CRYPT_FORMAT_CRYPTLIB:
1316 			readSequence( &stream, NULL );
1317 			status = readBignum( &stream, value1, DLPPARAM_MIN_SIG_R,
1318 								 CRYPT_MAX_PKCSIZE, maxRange );
1319 			if( cryptStatusError( status ) )
1320 				break;
1321 			status = readBignum( &stream, value2, DLPPARAM_MIN_SIG_S,
1322 								 CRYPT_MAX_PKCSIZE, maxRange );
1323 			break;
1324 #endif /* USE_INT_ASN1 */
1325 
1326 #ifdef USE_PGP
1327 		case CRYPT_FORMAT_PGP:
1328 			status = readBignumInteger16Ubits( &stream, value1,
1329 											   DLPPARAM_MIN_SIG_R,
1330 											   bytesToBits( CRYPT_MAX_PKCSIZE ),
1331 											   maxRange );
1332 			if( cryptStatusError( status ) )
1333 				break;
1334 			status = readBignumInteger16Ubits( &stream, value2,
1335 											   DLPPARAM_MIN_SIG_S,
1336 											   bytesToBits( CRYPT_MAX_PKCSIZE ),
1337 											   maxRange );
1338 			break;
1339 #endif /* USE_PGP */
1340 
1341 #ifdef USE_SSH
1342 		case CRYPT_IFORMAT_SSH:
1343 			status = importBignum( value1, buffer, 20, DLPPARAM_MIN_SIG_R,
1344 								   20, maxRange, KEYSIZE_CHECK_NONE );
1345 			if( cryptStatusError( status ) )
1346 				break;
1347 			status = importBignum( value2, buffer + 20, 20, DLPPARAM_MIN_SIG_S,
1348 								   20, maxRange, KEYSIZE_CHECK_NONE );
1349 			break;
1350 #endif /* USE_SSH */
1351 
1352 		default:
1353 			retIntError();
1354 		}
1355 
1356 	/* Clean up */
1357 	sMemDisconnect( &stream );
1358 	if( cryptStatusError( status ) )
1359 		return( status );
1360 
1361 	ENSURES( sanityCheckBignum( value1 ) );
1362 	ENSURES( sanityCheckBignum( value2 ) );
1363 
1364 	return( CRYPT_OK );
1365 	}
1366 
1367 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1368 
1369 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 5 ) ) \
IN_BUFFER(bufSize)1370 static int decodeECDLValuesFunction( IN_BUFFER( bufSize ) const BYTE *buffer,
1371 									 IN_LENGTH_SHORT_MIN( 32 ) const int bufSize,
1372 									 INOUT BIGNUM *value1,
1373 									 INOUT BIGNUM *value2,
1374 									 const BIGNUM *maxRange,
1375 									 IN_ENUM( CRYPT_FORMAT )  \
1376 										const CRYPT_FORMAT_TYPE formatType )
1377 	{
1378 	STREAM stream;
1379 	int status;
1380 
1381 	assert( isReadPtr( buffer, bufSize ) );
1382 	assert( isWritePtr( value1, sizeof( BIGNUM ) ) );
1383 	assert( isWritePtr( value2, sizeof( BIGNUM ) ) );
1384 	assert( isReadPtr( maxRange, sizeof( BIGNUM ) ) );
1385 
1386 	REQUIRES( bufSize >= 32 && bufSize < MAX_INTLENGTH_SHORT );
1387 	REQUIRES( formatType > CRYPT_FORMAT_NONE && \
1388 			  formatType < CRYPT_FORMAT_LAST );
1389 
1390 	/* Clear return values */
1391 	BN_clear( value1 );
1392 	BN_clear( value2 );
1393 
1394 	/* In most cases the DLP and ECDLP formats are identical and we can just
1395 	   pass the call on to the DLP form, however SSH uses totally different
1396 	   signature formats depending on whether the signature is DSA or ECDSA,
1397 	   so we handle the SSH format explicitly here */
1398 	if( formatType != CRYPT_IFORMAT_SSH )
1399 		{
1400 		return( decodeDLValuesFunction( buffer, bufSize, value1, value2,
1401 										maxRange, formatType ) );
1402 		}
1403 	sMemConnect( &stream, buffer, bufSize );
1404 	status = readBignumInteger32( &stream, value1, ECCPARAM_MIN_SIG_R,
1405 								  CRYPT_MAX_PKCSIZE_ECC, maxRange );
1406 	if( cryptStatusOK( status ) )
1407 		{
1408 		status = readBignumInteger32( &stream, value2, ECCPARAM_MIN_SIG_S,
1409 									  CRYPT_MAX_PKCSIZE_ECC, maxRange );
1410 		}
1411 	sMemDisconnect( &stream );
1412 	if( cryptStatusError( status ) )
1413 		return( status );
1414 
1415 	ENSURES( sanityCheckBignum( value1 ) );
1416 	ENSURES( sanityCheckBignum( value2 ) );
1417 
1418 	return( CRYPT_OK );
1419 	}
1420 #endif /* USE_ECDH || USE_ECDSA */
1421 
1422 /****************************************************************************
1423 *																			*
1424 *							Context Access Routines							*
1425 *																			*
1426 ****************************************************************************/
1427 
1428 STDC_NONNULL_ARG( ( 1 ) ) \
initPubKeyRead(INOUT CONTEXT_INFO * contextInfoPtr)1429 void initPubKeyRead( INOUT CONTEXT_INFO *contextInfoPtr )
1430 	{
1431 	const CRYPT_ALGO_TYPE cryptAlgo = contextInfoPtr->capabilityInfo->cryptAlgo;
1432 	PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
1433 
1434 	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1435 
1436 	REQUIRES_V( contextInfoPtr->type == CONTEXT_PKC );
1437 
1438 	/* Set the access method pointers */
1439 	if( isDlpAlgo( cryptAlgo ) )
1440 		{
1441 		FNPTR_SET( pkcInfo->readPublicKeyFunction, readPublicKeyDlpFunction );
1442 		FNPTR_SET( pkcInfo->decodeDLValuesFunction, decodeDLValuesFunction );
1443 		return;
1444 		}
1445 #if defined( USE_ECDH ) || defined( USE_ECDSA )
1446 	if( isEccAlgo( cryptAlgo ) )
1447 		{
1448 		FNPTR_SET( pkcInfo->readPublicKeyFunction, readPublicKeyEccFunction );
1449 		FNPTR_SET( pkcInfo->decodeDLValuesFunction, decodeECDLValuesFunction );
1450 		return;
1451 		}
1452 #endif /* USE_ECDH || USE_ECDSA */
1453 	FNPTR_SET( pkcInfo->readPublicKeyFunction, readPublicKeyRsaFunction );
1454 	}
1455 #else
1456 
1457 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readPublicKeyNullFunction(INOUT STREAM * stream,INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (KEYFORMAT)const KEYFORMAT_TYPE formatType)1458 static int readPublicKeyNullFunction( INOUT STREAM *stream,
1459 									  INOUT CONTEXT_INFO *contextInfoPtr,
1460 									  IN_ENUM( KEYFORMAT )  \
1461 										const KEYFORMAT_TYPE formatType )
1462 	{
1463 	return( CRYPT_ERROR_NOTAVAIL );
1464 	}
1465 
1466 STDC_NONNULL_ARG( ( 1 ) ) \
initPubKeyRead(INOUT CONTEXT_INFO * contextInfoPtr)1467 void initPubKeyRead( INOUT CONTEXT_INFO *contextInfoPtr )
1468 	{
1469 	FNPTR_SET( pkcInfo->readPublicKeyFunction, readPublicKeyNullFunction );
1470 	}
1471 #endif /* USE_PKC */
1472