📄 write.c
字号:
/* Write the serial number and signature algorithm identifier */
writeInteger( stream, certCertInfo->serialNumber,
certCertInfo->serialNumberLength, DEFAULT_TAG );
status = writeContextAlgoID( stream, iIssuerCryptContext,
certCertInfo->hashAlgo );
if( cryptStatusError( status ) )
return( status );
/* Write the issuer name, validity period, subject name, and public key
information */
if( issuerCertInfoPtr->subjectDNptr != NULL )
status = swrite( stream, issuerCertInfoPtr->subjectDNptr,
issuerCertInfoPtr->subjectDNsize );
else
status = writeDN( stream, subjectCertInfoPtr->issuerName, DEFAULT_TAG );
if( cryptStatusError( status ) )
return( status );
writeSequence( stream, sizeofUTCTime() * 2 );
writeUTCTime( stream, subjectCertInfoPtr->startTime, DEFAULT_TAG );
writeUTCTime( stream, subjectCertInfoPtr->endTime, DEFAULT_TAG );
status = writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
if( cryptStatusOK( status ) )
status = swrite( stream, subjectCertInfoPtr->publicKeyInfo,
subjectCertInfoPtr->publicKeyInfoSize );
if( cryptStatusError( status ) || extensionSize <= 0 )
return( status );
/* Write the extensions */
return( writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_CERTIFICATE, extensionSize ) );
}
/* Write attribute certificate information:
AttributeCertificateInfo ::= SEQUENCE {
version INTEGER DEFAULT(1),
owner [ 1 ] Name,
issuer Name,
signature AlgorithmIdentifier,
serialNumber INTEGER,
validity Validity,
attributes SEQUENCE OF Attribute,
extensions Extensions OPTIONAL
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
static int writeAttributeCertInfo( INOUT STREAM *stream,
INOUT CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
IN_HANDLE const CRYPT_CONTEXT iIssuerCryptContext )
{
const CERT_CERT_INFO *certCertInfo = subjectCertInfoPtr->cCertCert;
const int algoIdInfoSize = \
sizeofContextAlgoID( iIssuerCryptContext, certCertInfo->hashAlgo );
int length, extensionSize, issuerNameSize, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
assert( isReadPtr( issuerCertInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( isHandleRangeValid( iIssuerCryptContext ) );
if( cryptStatusError( algoIdInfoSize ) )
return( algoIdInfoSize );
/* Perform any necessary pre-encoding steps */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
PRE_SET_ISSUERDN | PRE_SET_ISSUERATTR | \
PRE_SET_VALIDITYPERIOD,
PRE_CHECK_DN | PRE_CHECK_ISSUERDN | \
PRE_CHECK_SERIALNO | \
( ( subjectCertInfoPtr->flags & CERT_FLAG_SELFSIGNED ) ? \
0 : PRE_CHECK_NONSELFSIGNED_DN ),
( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
PRE_FLAG_DN_IN_ISSUERCERT : PRE_FLAG_NONE );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how the issuer name will be encoded */
issuerNameSize = ( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
issuerCertInfoPtr->subjectDNsize : \
sizeofDN( subjectCertInfoPtr->issuerName );
/* Determine the size of the certificate information */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
if( cryptStatusError( extensionSize ) )
return( extensionSize );
length = ( int ) sizeofObject( sizeofDN( subjectCertInfoPtr->subjectName ) ) + \
issuerNameSize + \
algoIdInfoSize + \
sizeofInteger( certCertInfo->serialNumber,
certCertInfo->serialNumberLength ) + \
sizeofObject( sizeofUTCTime() * 2 ) + \
sizeofObject( 0 ) + \
( ( extensionSize > 0 ) ? \
( int ) sizeofObject( extensionSize ) : 0 );
/* Write the outer SEQUENCE wrapper */
writeSequence( stream, length );
/* Write the owner and issuer name */
writeConstructed( stream, sizeofDN( subjectCertInfoPtr->subjectName ),
CTAG_AC_ENTITYNAME );
status = writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
if( cryptStatusOK( status ) )
{
if( issuerCertInfoPtr->subjectDNptr != NULL )
status = swrite( stream, issuerCertInfoPtr->subjectDNptr,
issuerCertInfoPtr->subjectDNsize );
else
status = writeDN( stream, subjectCertInfoPtr->issuerName, DEFAULT_TAG );
}
if( cryptStatusError( status ) )
return( status );
/* Write the signature algorithm identifier, serial number and validity
period */
writeContextAlgoID( stream, iIssuerCryptContext, certCertInfo->hashAlgo );
writeInteger( stream, certCertInfo->serialNumber,
certCertInfo->serialNumberLength, DEFAULT_TAG );
writeSequence( stream, sizeofUTCTime() * 2 );
writeUTCTime( stream, subjectCertInfoPtr->startTime, DEFAULT_TAG );
writeUTCTime( stream, subjectCertInfoPtr->endTime, DEFAULT_TAG );
/* Write the attributes */
status = writeSequence( stream, 0 );
if( cryptStatusError( status ) || extensionSize <= 0 )
return( status );
/* Write the extensions */
return( writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_ATTRIBUTE_CERT, extensionSize ) );
}
/* Write certificate request information:
CertificationRequestInfo ::= SEQUENCE {
version INTEGER (0),
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
attributes [ 0 ] SET OF Attribute
}
If extensions are present they are encoded as:
SEQUENCE { -- Attribute from X.501
OBJECT IDENTIFIER {pkcs-9 14}, -- type
SET OF { -- values
SEQUENCE OF { -- ExtensionReq from CMMF draft
<X.509v3 extensions>
}
}
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeCertRequestInfo( INOUT STREAM *stream,
INOUT CERT_INFO *subjectCertInfoPtr,
STDC_UNUSED const CERT_INFO *issuerCertInfoPtr,
IN_HANDLE const CRYPT_CONTEXT iIssuerCryptContext )
{
int length, extensionSize, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( issuerCertInfoPtr == NULL );
REQUIRES( isHandleRangeValid( iIssuerCryptContext ) );/* Not used here */
/* Make sure that everything is in order */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, NULL, PRE_SET_NONE,
PRE_CHECK_SPKI | PRE_CHECK_DN_PARTIAL,
PRE_FLAG_NONE );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how big the encoded certificate request will be */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
if( cryptStatusError( extensionSize ) )
return( extensionSize );
length = sizeofShortInteger( 0 ) + \
sizeofDN( subjectCertInfoPtr->subjectName ) + \
subjectCertInfoPtr->publicKeyInfoSize;
if( extensionSize > 0 )
{
length += sizeofObject( \
sizeofObject( \
sizeofOID( OID_PKCS9_EXTREQ ) + \
sizeofObject( sizeofObject( extensionSize ) ) ) );
}
else
length += ( int ) sizeofObject( 0 );
/* Write the header, version number, DN, and public key info */
writeSequence( stream, length );
writeShortInteger( stream, 0, DEFAULT_TAG );
status = writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
if( cryptStatusOK( status ) )
status = swrite( stream, subjectCertInfoPtr->publicKeyInfo,
subjectCertInfoPtr->publicKeyInfoSize );
if( cryptStatusError( status ) )
return( status );
/* Write the attributes. If there are no attributes, we have to write
an (erroneous) zero-length field */
if( extensionSize <= 0 )
return( writeConstructed( stream, 0, CTAG_CR_ATTRIBUTES ) );
writeConstructed( stream, ( int ) \
sizeofObject( \
sizeofOID( OID_PKCS9_EXTREQ ) + \
sizeofObject( sizeofObject( extensionSize ) ) ),
CTAG_CR_ATTRIBUTES );
return( writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_CERTREQUEST, extensionSize ) );
}
/* Write CRMF certificate request information:
CertReq ::= SEQUENCE {
certReqID INTEGER (0),
certTemplate SEQUENCE {
validity [ 4 ] SEQUENCE {
validFrom [ 0 ] EXPLICIT GeneralizedTime OPTIONAL,
validTo [ 1 ] EXPLICIT GeneralizedTime OPTIONAL
} OPTIONAL,
subject [ 5 ] EXPLICIT Name OPTIONAL,
publicKey [ 6 ] SubjectPublicKeyInfo,
extensions [ 9 ] SET OF Attribute OPTIONAL
}
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeCrmfRequestInfo( INOUT STREAM *stream,
INOUT CERT_INFO *subjectCertInfoPtr,
STDC_UNUSED const CERT_INFO *issuerCertInfoPtr,
IN_HANDLE const CRYPT_CONTEXT iIssuerCryptContext )
{
int payloadLength, extensionSize, subjectDNsize = 0, timeSize = 0;
int status = CRYPT_OK;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( issuerCertInfoPtr == NULL );
REQUIRES( isHandleRangeValid( iIssuerCryptContext ) );/* Not used here */
/* Make sure that everything is in order */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, NULL, PRE_SET_NONE,
PRE_CHECK_SPKI | \
( ( subjectCertInfoPtr->subjectName != NULL ) ? \
PRE_CHECK_DN_PARTIAL : 0 ),
PRE_FLAG_NONE );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how big the encoded certificate request will be */
if( subjectCertInfoPtr->subjectName != NULL )
subjectCertInfoPtr->subjectDNsize = subjectDNsize = \
sizeofDN( subjectCertInfoPtr->subjectName );
if( subjectCertInfoPtr->startTime > MIN_TIME_VALUE )
timeSize = sizeofObject( sizeofGeneralizedTime() );
if( subjectCertInfoPtr->endTime > MIN_TIME_VALUE )
timeSize += sizeofObject( sizeofGeneralizedTime() );
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
if( cryptStatusError( extensionSize ) )
return( extensionSize );
payloadLength = ( ( timeSize > 0 ) ? sizeofObject( timeSize ) : 0 ) + \
( ( subjectDNsize > 0 ) ? sizeofObject( subjectDNsize ) : 0 ) + \
subjectCertInfoPtr->publicKeyInfoSize;
if( extensionSize )
payloadLength += sizeofObject( extensionSize );
/* Write the header, request ID, inner header, DN, and public key */
writeSequence( stream, sizeofShortInteger( 0 ) + \
sizeofObject( payloadLength ) );
writeShortInteger( stream, 0, DEFAULT_TAG );
writeSequence( stream, payloadLength );
if( timeSize > 0 )
{
writeConstructed( stream, timeSize, CTAG_CF_VALIDITY );
if( subjectCertInfoPtr->startTime > MIN_TIME_VALUE )
{
writeConstructed( stream, sizeofGeneralizedTime(), 0 );
writeGeneralizedTime( stream, subjectCertInfoPtr->startTime,
DEFAULT_TAG );
}
if( subjectCertInfoPtr->endTime > MIN_TIME_VALUE )
{
writeConstructed( stream, sizeofGeneralizedTime(), 1 );
writeGeneralizedTime( stream, subjectCertInfoPtr->endTime,
DEFAULT_TAG );
}
}
if( subjectDNsize > 0 )
{
writeConstructed( stream, subjectCertInfoPtr->subjectDNsize,
CTAG_CF_SUBJECT );
status = writeDN( stream, subjectCertInfoPtr->subjectName,
DEFAULT_TAG );
if( cryptStatusError( status ) )
return( status );
}
if( !sIsNullStream( stream ) )
{
/* Convert the SPKI SEQUENCE tag to the CRMF alternative */
sputc( stream, MAKE_CTAG( CTAG_CF_PUBLICKEY ) );
swrite( stream, ( BYTE * ) subjectCertInfoPtr->publicKeyInfo + 1,
subjectCertInfoPtr->publicKeyInfoSize - 1 );
}
else
{
swrite( stream, subjectCertInfoPtr->publicKeyInfo,
subjectCertInfoPtr->publicKeyInfoSize );
}
if( cryptStatusError( status ) || extensionSize <= 0 )
return( status );
/* Write the attributes */
writeConstructed( stream, extensionSize, CTAG_CF_EXTENSIONS );
return( writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_REQUEST_CERT, extensionSize ) );
}
/* Write CMP revocation request information:
RevDetails ::= SEQUENCE {
certTemplate SEQUENCE {
serialNumber [ 1 ] INTEGER,
issuer [ 3 ] EXPLICIT Name,
},
crlEntryDetails SET OF Attribute
} */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int writeRevRequestInfo( INOUT STREAM *stream,
INOUT CERT_INFO *subjectCertInfoPtr,
STDC_UNUSED const CERT_INFO *issuerCertInfoPtr,
STDC_UNUSED const CRYPT_CONTEXT iIssuerCryptContext )
{
int payloadLength, extensionSize, status;
assert( isWritePtr( stream, sizeof( STREAM ) ) );
assert( isWritePtr( subjectCertInfoPtr, sizeof( CERT_INFO ) ) );
REQUIRES( issuerCertInfoPtr == NULL );
REQUIRES( iIssuerCryptContext == CRYPT_UNUSED );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -