23 #ifdef USE_CERTIFICATES
31 #if defined( USE_CERTREV ) || defined( USE_CERTVAL )
53 if( attributePtr == NULL )
63 CRYPT_IATTRIBUTE_RANDOM_NONCE );
66 return( addAttributeFieldString( attributePtrPtr, nonceType,
72 status = getAttributeDataPtr( attributePtr, &noncePtr, &nonceLength );
78 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE ) );
107 const CERT_CERT_INFO *certCertInfo = subjectCertInfoPtr->cCertCert;
117 if( sIsNullStream( stream ) )
127 status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
132 status = preCheckCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
137 ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
145 subjectCertInfoPtr->issuerDNsize = \
146 ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
148 sizeofDN( subjectCertInfoPtr->issuerName );
149 subjectCertInfoPtr->subjectDNsize = \
150 sizeofDN( subjectCertInfoPtr->subjectName );
156 return( algoIdInfoSize );
159 return( extensionSize );
167 if( extensionSize > 0 )
170 sizeofObject( sizeofObject( extensionSize ) );
174 writeSequence( stream, length );
177 if( extensionSize > 0 )
185 writeInteger( stream, certCertInfo->serialNumber,
187 status = writeContextAlgoID( stream, iIssuerCryptContext,
194 if( issuerCertInfoPtr->subjectDNptr != NULL )
195 status = swrite( stream, issuerCertInfoPtr->subjectDNptr,
198 status = writeDN( stream, subjectCertInfoPtr->issuerName,
DEFAULT_TAG );
202 writeUTCTime( stream, subjectCertInfoPtr->startTime,
DEFAULT_TAG );
203 writeUTCTime( stream, subjectCertInfoPtr->endTime,
DEFAULT_TAG );
204 status = writeDN( stream, subjectCertInfoPtr->subjectName,
DEFAULT_TAG );
206 status = swrite( stream, subjectCertInfoPtr->publicKeyInfo,
207 subjectCertInfoPtr->publicKeyInfoSize );
212 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
264 static
int writeAttributeCertInfo(
INOUT STREAM *stream,
269 const CERT_CERT_INFO *certCertInfo = subjectCertInfoPtr->cCertCert;
270 int algoIdInfoSize,
length, extensionSize;
271 int issuerNameSize, holderNameSize,
status;
280 if( sIsNullStream( stream ) )
282 status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
287 status = preCheckCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
292 ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
300 issuerNameSize = ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
302 sizeofDN( subjectCertInfoPtr->issuerName );
303 holderNameSize =
sizeofDN( subjectCertInfoPtr->subjectName );
309 return( algoIdInfoSize );
312 return( extensionSize );
314 sizeofObject( sizeofObject( sizeofObject( holderNameSize ) ) ) + \
315 sizeofObject( sizeofObject( sizeofObject( issuerNameSize ) ) ) + \
317 sizeofInteger( certCertInfo->serialNumber,
321 if( extensionSize > 0 )
322 length += ( int ) sizeofObject( extensionSize );
325 writeSequence( stream, length );
329 writeSequence( stream, sizeofObject( sizeofObject( holderNameSize ) ) );
330 writeConstructed( stream, sizeofObject( holderNameSize ),
332 writeConstructed( stream, holderNameSize, 4 );
333 status = writeDN( stream, subjectCertInfoPtr->subjectName,
DEFAULT_TAG );
336 writeConstructed( stream,
337 sizeofObject( sizeofObject( issuerNameSize ) ), 0 );
338 writeSequence( stream, sizeofObject( issuerNameSize ) );
339 writeConstructed( stream, issuerNameSize, 4 );
340 if( issuerCertInfoPtr->subjectDNptr != NULL )
341 status = swrite( stream, issuerCertInfoPtr->subjectDNptr,
344 status = writeDN( stream, subjectCertInfoPtr->issuerName,
DEFAULT_TAG );
351 writeContextAlgoID( stream, iIssuerCryptContext, certCertInfo->
hashAlgo );
352 writeInteger( stream, certCertInfo->serialNumber,
355 writeGeneralizedTime( stream, subjectCertInfoPtr->startTime,
357 status = writeGeneralizedTime( stream, subjectCertInfoPtr->endTime,
363 status = writeSequence( stream, 0 );
368 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
398 const CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
399 REVOCATION_INFO *revocationInfo;
401 int length, algoIdInfoSize, extensionSize, revocationInfoLength = 0;
402 int iterationCount,
status;
406 assert( ( issuerCertInfoPtr == NULL && \
411 REQUIRES( ( issuerCertInfoPtr == NULL && \
413 ( issuerCertInfoPtr != NULL && \
417 if( sIsNullStream( stream ) )
421 status = preEncodeCertificate( subjectCertInfoPtr, NULL,
426 status = preEncodeCertificate( subjectCertInfoPtr,
433 status = preCheckCertificate( subjectCertInfoPtr,
444 subjectCertInfoPtr->version = \
445 ( subjectCertInfoPtr->attributes != NULL ) ? 2 : 1;
446 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
448 revocationInfo = revocationInfo->next, iterationCount++ )
450 const int crlEntrySize = sizeofCRLentry( revocationInfo );
453 return( crlEntrySize );
454 revocationInfoLength += crlEntrySize;
457 if( revocationInfo->attributes != NULL )
458 subjectCertInfoPtr->version = 2;
466 return( writeCRLentry( stream, certRevInfo->currentRevocation ) );
470 certRevInfo->hashAlgo );
472 return( algoIdInfoSize );
475 return( extensionSize );
476 length = algoIdInfoSize +
\
481 sizeofObject( revocationInfoLength );
482 if( extensionSize > 0 )
485 sizeofObject( sizeofObject( extensionSize ) );
489 writeSequence( stream, length );
492 if( extensionSize > 0 )
496 status = writeContextAlgoID( stream, iIssuerCryptContext,
497 certRevInfo->hashAlgo );
500 swrite( stream, issuerCertInfoPtr->subjectDNptr,
501 issuerCertInfoPtr->subjectDNsize );
502 status = writeUTCTime( stream, subjectCertInfoPtr->startTime,
505 status = writeUTCTime( stream, subjectCertInfoPtr->endTime,
512 status = writeSequence( stream, revocationInfoLength );
513 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
516 revocationInfo = revocationInfo->next, iterationCount++ )
518 status = writeCRLentry( stream, revocationInfo );
526 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
560 static
int writeCertRequestInfo(
INOUT STREAM *stream,
570 REQUIRES( issuerCertInfoPtr == NULL );
574 if( sIsNullStream( stream ) )
576 status = preCheckCertificate( subjectCertInfoPtr, NULL,
586 return( extensionSize );
588 sizeofDN( subjectCertInfoPtr->subjectName ) +
\
590 if( extensionSize > 0 )
592 length += sizeofObject( \
595 sizeofObject( sizeofObject( extensionSize ) ) ) );
598 length += ( int ) sizeofObject( 0 );
601 writeSequence( stream, length );
603 status = writeDN( stream, subjectCertInfoPtr->subjectName,
DEFAULT_TAG );
605 status = swrite( stream, subjectCertInfoPtr->publicKeyInfo,
606 subjectCertInfoPtr->publicKeyInfoSize );
612 if( extensionSize <= 0 )
614 writeConstructed( stream, (
int ) \
617 sizeofObject( sizeofObject( extensionSize ) ) ),
619 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
639 static
int writeCrmfRequestInfo(
INOUT STREAM *stream,
644 int payloadLength, extensionSize, subjectDNsize = 0, timeSize = 0;
650 REQUIRES( issuerCertInfoPtr == NULL );
654 if( sIsNullStream( stream ) )
656 status = preCheckCertificate( subjectCertInfoPtr, NULL,
658 ( ( subjectCertInfoPtr->subjectName != NULL ) ? \
666 payloadLength = subjectCertInfoPtr->publicKeyInfoSize;
667 if( subjectCertInfoPtr->subjectName != NULL )
669 subjectCertInfoPtr->subjectDNsize = subjectDNsize = \
670 sizeofDN( subjectCertInfoPtr->subjectName );
671 payloadLength += sizeofObject( subjectDNsize );
678 payloadLength += sizeofObject( timeSize );
681 return( extensionSize );
682 if( extensionSize > 0 )
683 payloadLength += sizeofObject( extensionSize );
687 sizeofObject( payloadLength ) );
689 writeSequence( stream, payloadLength );
696 writeGeneralizedTime( stream, subjectCertInfoPtr->startTime,
702 writeGeneralizedTime( stream, subjectCertInfoPtr->endTime,
706 if( subjectDNsize > 0 )
708 writeConstructed( stream, subjectCertInfoPtr->subjectDNsize,
710 status = writeDN( stream, subjectCertInfoPtr->subjectName,
717 swrite( stream, (
BYTE * ) subjectCertInfoPtr->publicKeyInfo + 1,
718 subjectCertInfoPtr->publicKeyInfoSize - 1 );
724 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
739 static
int writeRevRequestInfo(
INOUT STREAM *stream,
749 REQUIRES( issuerCertInfoPtr == NULL );
753 if( sIsNullStream( stream ) )
755 status = preCheckCertificate( subjectCertInfoPtr, NULL,
765 return( extensionSize );
766 payloadLength =
sizeofInteger( subjectCertInfoPtr->cCertCert->serialNumber,
767 subjectCertInfoPtr->cCertCert->serialNumberLength ) + \
768 sizeofObject( subjectCertInfoPtr->issuerDNsize );
769 if( extensionSize > 0 )
770 payloadLength += sizeofObject( extensionSize );
773 writeSequence( stream, sizeofObject( payloadLength ) );
774 writeSequence( stream, payloadLength );
775 writeInteger( stream, subjectCertInfoPtr->cCertCert->serialNumber,
776 subjectCertInfoPtr->cCertCert->serialNumberLength,
778 writeConstructed( stream, subjectCertInfoPtr->issuerDNsize,
780 status = swrite( stream, subjectCertInfoPtr->issuerDNptr,
781 subjectCertInfoPtr->issuerDNsize );
787 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
810 static
int writeRtcsRequestInfo(
INOUT STREAM *stream,
816 CERT_VAL_INFO *certValInfo = subjectCertInfoPtr->cCertVal;
817 VALIDITY_INFO *validityInfo;
818 int length, extensionSize, requestInfoLength = 0;
819 int iterationCount,
status;
824 REQUIRES( issuerCertInfoPtr == NULL );
828 if( sIsNullStream( stream ) )
831 status = setNonce( &subjectCertInfoPtr->attributes,
837 status = preCheckCertificate( subjectCertInfoPtr, NULL,
844 for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
845 validityInfo != NULL && \
847 validityInfo = validityInfo->next, iterationCount++ )
849 const int requestEntrySize = sizeofRtcsRequestEntry( validityInfo );
852 return( requestEntrySize );
853 requestInfoLength += requestEntrySize;
858 return( extensionSize );
859 length = sizeofObject( requestInfoLength ) + \
860 ( ( extensionSize > 0 ) ? sizeofObject( extensionSize ) : 0 );
863 writeSequence( stream, length );
866 status = writeSequence( stream, requestInfoLength );
867 for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
870 validityInfo = validityInfo->next, iterationCount++ )
872 status = writeRtcsRequestEntry( stream, validityInfo );
879 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
891 static
int writeRtcsResponseInfo(
INOUT STREAM *stream,
897 CERT_VAL_INFO *certValInfo = subjectCertInfoPtr->cCertVal;
898 VALIDITY_INFO *validityInfo;
899 int extensionSize, validityInfoLength = 0, iterationCount,
status;
904 REQUIRES( issuerCertInfoPtr == NULL );
912 if( sIsNullStream( stream ) )
914 status = preEncodeCertificate( subjectCertInfoPtr, NULL,
921 for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
923 validityInfo = validityInfo->next, iterationCount++ )
925 const int responseEntrySize = \
926 sizeofRtcsResponseEntry( validityInfo,
931 return( responseEntrySize );
932 validityInfoLength += responseEntrySize;
937 return( extensionSize );
941 status = writeSequence( stream, validityInfoLength );
942 for( validityInfo = certValInfo->validityInfo, iterationCount = 0;
945 validityInfo = validityInfo->next, iterationCount++ )
947 status = writeRtcsResponseEntry( stream, validityInfo,
956 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
991 static
int writeOcspRequestInfo(
INOUT STREAM *stream,
997 CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
998 REVOCATION_INFO *revocationInfo;
999 int length, extensionSize, revocationInfoLength = 0;
1000 int iterationCount,
status;
1004 assert( issuerCertInfoPtr == NULL || \
1011 if( sIsNullStream( stream ) )
1014 status = setNonce( &subjectCertInfoPtr->attributes,
1020 status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
1024 if( issuerCertInfoPtr != NULL )
1027 status = preCheckCertificate( subjectCertInfoPtr,
1035 status = preCheckCertificate( subjectCertInfoPtr, NULL,
1044 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
1045 revocationInfo != NULL && \
1047 revocationInfo = revocationInfo->next, iterationCount++ )
1049 const int requestEntrySize = sizeofOcspRequestEntry( revocationInfo );
1052 return( requestEntrySize );
1053 revocationInfoLength += requestEntrySize;
1058 return( extensionSize );
1059 length = ( ( subjectCertInfoPtr->version == 2 ) ? \
1061 ( ( issuerCertInfoPtr != NULL ) ? \
1062 sizeofObject( sizeofObject( issuerCertInfoPtr->subjectDNsize ) ) : 0 ) + \
1063 sizeofObject( revocationInfoLength );
1064 if( extensionSize > 0 )
1065 length += sizeofObject( sizeofObject( extensionSize ) );
1068 writeSequence( stream, length );
1071 if( subjectCertInfoPtr->version == 2 )
1078 if( issuerCertInfoPtr != NULL )
1080 writeConstructed( stream,
1081 sizeofObject( issuerCertInfoPtr->subjectDNsize ), 1 );
1082 writeConstructed( stream, issuerCertInfoPtr->subjectDNsize, 4 );
1083 status = swrite( stream, issuerCertInfoPtr->subjectDNptr,
1084 issuerCertInfoPtr->subjectDNsize );
1091 status = writeSequence( stream, revocationInfoLength );
1092 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
1095 revocationInfo = revocationInfo->next, iterationCount++ )
1097 status = writeOcspRequestEntry( stream, revocationInfo );
1104 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
1119 static
int writeOcspResponseInfo(
INOUT STREAM *stream,
1125 CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
1126 REVOCATION_INFO *revocationInfo;
1127 int length, extensionSize, revocationInfoLength = 0;
1128 int iterationCount,
status;
1137 if( sIsNullStream( stream ) )
1139 status = preCheckCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
1148 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
1149 revocationInfo != NULL && \
1151 revocationInfo = revocationInfo->next, iterationCount++ )
1153 const int responseEntrySize = sizeofOcspResponseEntry( revocationInfo );
1156 return( responseEntrySize );
1157 revocationInfoLength += responseEntrySize;
1162 return( extensionSize );
1165 sizeofGeneralizedTime() + \
1166 sizeofObject( revocationInfoLength );
1167 if( extensionSize > 0 )
1168 length += sizeofObject( sizeofObject( extensionSize ) );
1172 writeSequence( stream, length );
1175 writeConstructed( stream, issuerCertInfoPtr->
subjectDNsize, 1 );
1176 swrite( stream, issuerCertInfoPtr->subjectDNptr,
1178 status = writeGeneralizedTime( stream, subjectCertInfoPtr->startTime,
1185 status = writeSequence( stream, revocationInfoLength );
1186 for( revocationInfo = certRevInfo->revocations, iterationCount = 0;
1189 revocationInfo = revocationInfo->next, iterationCount++ )
1191 status = writeOcspResponseEntry( stream, revocationInfo,
1192 subjectCertInfoPtr->startTime );
1199 return( writeAttributes( stream, subjectCertInfoPtr->attributes,
1215 static
int writeCmsAttributes(
INOUT STREAM *stream,
1225 REQUIRES( issuerCertInfoPtr == NULL );
1227 REQUIRES( attributeInfoPtr->attributes != NULL );
1251 if( !addDefaultAttributes )
1260 status = addCertComponent( attributeInfoPtr,
1271 if( addDefaultAttributes && \
1275 const time_t currentTime =
getTime();
1286 status = addCertComponentString( attributeInfoPtr,
1288 ¤tTime,
sizeof( time_t ) );
1295 status = checkAttributes(
ATTRIBUTE_CMS, attributeInfoPtr->attributes,
1296 &attributeInfoPtr->errorLocus,
1297 &attributeInfoPtr->errorType );
1302 return( attributeSize );
1305 return( writeAttributes( stream, attributeInfoPtr->attributes,
1328 static
int getPkiUserInfo(
INOUT CERT_PKIUSER_INFO *certUserInfo,
1329 OUT_BUFFER( maxUserInfoSize, *userInfoSize ) \
1344 assert(
isWritePtr( certUserInfo,
sizeof( CERT_PKIUSER_INFO ) ) );
1345 assert(
isWritePtr( userInfo, maxUserInfoSize ) );
1346 assert(
isWritePtr( userInfoSize,
sizeof(
int ) ) );
1347 assert(
isWritePtr( algoID, maxAlgoIdSize ) );
1348 assert(
isWritePtr( algoIdSize,
sizeof(
int ) ) );
1350 REQUIRES( maxUserInfoSize >= 64 && \
1355 memset( userInfo, 0, maxUserInfoSize );
1356 memset( algoID, 0, maxAlgoIdSize );
1357 *userInfoSize = *algoIdSize = 0;
1387 certUserInfo->pkiIssuePW,
1393 certUserInfo->pkiRevPW,
1401 sMemOpen( &stream, userInfo, maxUserInfoSize );
1403 writeOctetString( &stream, certUserInfo->pkiIssuePW,
1405 status = writeOctetString( &stream, certUserInfo->pkiRevPW,
1408 userInfoBufPos = stell( &stream );
1409 sMemDisconnect( &stream );
1450 for( i = 0; i < 2; i++ )
1451 userInfo[ userInfoBufPos++ ] = 2;
1455 userInfo, userInfoBufPos );
1458 sMemOpen( &stream, algoID, maxAlgoIdSize );
1459 status = writeCryptContextAlgoID( &stream, iCryptContext );
1461 *algoIdSize = stell( &stream );
1462 sMemDisconnect( &stream );
1467 *userInfoSize = userInfoBufPos;
1473 static
int writePkiUserInfo(
INOUT STREAM *stream,
1478 CERT_PKIUSER_INFO *certUserInfo = userInfoPtr->cCertUser;
1479 BYTE userInfo[ 128 + 8 ], algoID[ 128 + 8 ];
1480 int extensionSize, userInfoSize, algoIdSize,
status;
1485 REQUIRES( issuerCertInfoPtr == NULL );
1488 if( sIsNullStream( stream ) )
1506 &msgData, CRYPT_IATTRIBUTE_RANDOM_NONCE );
1509 char encodedKeyID[ 32 + 8 ];
1512 status = encodePKIUserValue( encodedKeyID, 32, &encKeyIdSize,
1515 status = decodePKIUserValue( keyID, 16, &keyIDlength,
1516 encodedKeyID, encKeyIdSize );
1520 status = addAttributeFieldString( &userInfoPtr->attributes,
1523 keyIDlength, 0, &dummy1, &dummy2 );
1527 userInfoPtr->attributes,
1528 &userInfoPtr->errorLocus,
1529 &userInfoPtr->errorType );
1547 status = getPkiUserInfo( certUserInfo, userInfo, 128, &userInfoSize,
1548 algoID, 128, &algoIdSize );
1554 userInfoPtr->subjectDNsize =
sizeofDN( userInfoPtr->subjectName );
1557 return( extensionSize );
1562 status = writeDN( stream, userInfoPtr->subjectName,
DEFAULT_TAG );
1565 swrite( stream, algoID, algoIdSize );
1566 writeOctetString( stream, userInfo, userInfoSize,
DEFAULT_TAG );
1567 return( writeAttributes( stream, userInfoPtr->attributes,
1580 const WRITECERT_FUNCTION
function;
1582 static const CERTWRITE_INFO
FAR_BSS certWriteTable[] = {
1624 if( certWriteTable[ i ].
type == certType )
1625 return( certWriteTable[ i ].
function );