📄 write.c
字号:
/* Write the signature algorithm identifier, serial number and validity
period */
writeContextAlgoID( stream, iIssuerCryptContext, certCertInfo->hashAlgo,
ALGOID_FLAG_ALGOID_ONLY );
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( 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>
}
}
}
as per the CMMF draft */
static int writeCertRequestInfo( STREAM *stream,
CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
int length, extensionSize, status;
assert( issuerCertInfoPtr == NULL );
/* Make sure everything is in order */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_CERTREQUEST );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how big the encoded certificate request will be */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
length = sizeofShortInteger( 0 ) + \
sizeofDN( subjectCertInfoPtr->subjectName ) + \
subjectCertInfoPtr->publicKeyInfoSize;
if( extensionSize > 0 )
length += ( int ) \
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
}
} */
static int writeCrmfRequestInfo( STREAM *stream,
CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
int payloadLength, extensionSize, subjectDNsize = 0, timeSize = 0;
int status = CRYPT_OK;
assert( issuerCertInfoPtr == NULL );
/* Make sure everything is in order */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_REQUEST_CERT );
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 )
timeSize = ( int ) sizeofObject( sizeofGeneralizedTime() );
if( subjectCertInfoPtr->endTime )
timeSize += ( int ) sizeofObject( sizeofGeneralizedTime() );
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
payloadLength = ( timeSize ? ( int ) sizeofObject( timeSize ) : 0 ) + \
( subjectDNsize ? ( int ) sizeofObject( subjectDNsize ) : 0 ) + \
subjectCertInfoPtr->publicKeyInfoSize;
if( extensionSize )
payloadLength += ( int ) 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 )
{
writeConstructed( stream, timeSize, CTAG_CF_VALIDITY );
if( subjectCertInfoPtr->startTime )
{
writeConstructed( stream, sizeofGeneralizedTime(), 0 );
writeGeneralizedTime( stream, subjectCertInfoPtr->startTime,
DEFAULT_TAG );
}
if( subjectCertInfoPtr->endTime )
{
writeConstructed( stream, sizeofGeneralizedTime(), 1 );
writeGeneralizedTime( stream, subjectCertInfoPtr->endTime,
DEFAULT_TAG );
}
}
if( subjectDNsize )
{
writeConstructed( stream, subjectCertInfoPtr->subjectDNsize,
CTAG_CF_SUBJECT );
status = writeDN( stream, subjectCertInfoPtr->subjectName,
DEFAULT_TAG );
if( cryptStatusError( status ) )
return( status );
}
if( !sIsNullStream( stream ) )
{
BYTE *dataPtr = sMemBufPtr( stream );
/* Convert the SPKI SEQUENCE tag to the CRMF alternative */
swrite( stream, subjectCertInfoPtr->publicKeyInfo,
subjectCertInfoPtr->publicKeyInfoSize );
*dataPtr = MAKE_CTAG( CTAG_CF_PUBLICKEY );
}
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
} */
static int writeRevRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
int payloadLength, extensionSize, status;
assert( issuerCertInfoPtr == NULL );
assert( iIssuerCryptContext == CRYPT_UNUSED );
/* Make sure everything is in order */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_REQUEST_REVOCATION );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how big the encoded certificate request will be */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
payloadLength = sizeofInteger( subjectCertInfoPtr->cCertCert->serialNumber,
subjectCertInfoPtr->cCertCert->serialNumberLength ) + \
sizeofObject( subjectCertInfoPtr->issuerDNsize ) + \
( extensionSize ? ( int ) sizeofObject( extensionSize ) : 0 );
/* Write the header, inner header, serial number and issuer DN */
writeSequence( stream, sizeofObject( payloadLength ) );
writeSequence( stream, payloadLength );
writeInteger( stream, subjectCertInfoPtr->cCertCert->serialNumber,
subjectCertInfoPtr->cCertCert->serialNumberLength,
CTAG_CF_SERIALNUMBER );
writeConstructed( stream, subjectCertInfoPtr->issuerDNsize,
CTAG_CF_ISSUER );
status = swrite( stream, subjectCertInfoPtr->issuerDNptr,
subjectCertInfoPtr->issuerDNsize );
if( cryptStatusError( status ) || extensionSize <= 0 )
return( status );
/* Write the attributes */
writeConstructed( stream, extensionSize, CTAG_CF_EXTENSIONS );
return( writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_REQUEST_REVOCATION, extensionSize ) );
}
/* Write CRL information:
CRLInfo ::= SEQUENCE {
version INTEGER DEFAULT(0),
signature AlgorithmIdentifier,
issuer Name,
thisUpdate UTCTime,
nextUpdate UTCTime OPTIONAL,
revokedCertificates SEQUENCE OF RevokedCerts,
extensions [ 0 ] Extensions OPTIONAL
} */
static int writeCRLInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
const CERT_REV_INFO *certRevInfo = subjectCertInfoPtr->cCertRev;
REVOCATION_INFO *revocationInfo;
int length, extensionSize, revocationInfoLength = 0, status;
assert( ( isReadPtr( issuerCertInfoPtr, sizeof( CERT_INFO ) ) && \
isHandleRangeValid( iIssuerCryptContext ) ) || \
( issuerCertInfoPtr == NULL && \
iIssuerCryptContext == CRYPT_UNUSED ) );
/* Perform any necessary pre-encoding steps */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_CRL );
if( cryptStatusError( status ) )
return( status );
}
/* Process CRL entries and version information */
subjectCertInfoPtr->version = \
( subjectCertInfoPtr->attributes != NULL ) ? 2 : 1;
for( revocationInfo = certRevInfo->revocations;
revocationInfo != NULL; revocationInfo = revocationInfo->next )
{
if( revocationInfo->attributes != NULL )
/* If there are per-entry extensions present it's a v2 CRL */
subjectCertInfoPtr->version = 2;
revocationInfoLength += sizeofCRLentry( revocationInfo );
}
/* If we're being asked to write a single CRL entry, we don't try and go
any further since the remaining CRL fields (and issuer info) may not
be set up */
if( issuerCertInfoPtr == NULL )
return( writeCRLentry( stream, certRevInfo->currentRevocation ) );
/* Determine how big the encoded CRL will be */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
length = sizeofContextAlgoID( iIssuerCryptContext, certRevInfo->hashAlgo,
ALGOID_FLAG_ALGOID_ONLY ) + \
issuerCertInfoPtr->subjectDNsize + sizeofUTCTime() + \
( subjectCertInfoPtr->endTime ? sizeofUTCTime() : 0 ) + \
sizeofObject( revocationInfoLength );
if( extensionSize > 0 )
length += sizeofShortInteger( X509VERSION_2 ) + \
( int ) sizeofObject( sizeofObject( extensionSize ) );
/* Write the outer SEQUENCE wrapper */
writeSequence( stream, length );
/* If there are extensions present, mark this as a v2 CRL */
if( extensionSize )
writeShortInteger( stream, X509VERSION_2, DEFAULT_TAG );
/* Write the signature algorithm identifier, issuer name, and CRL time */
status = writeContextAlgoID( stream, iIssuerCryptContext,
certRevInfo->hashAlgo,
ALGOID_FLAG_ALGOID_ONLY );
if( cryptStatusError( status ) )
return( status );
swrite( stream, issuerCertInfoPtr->subjectDNptr,
issuerCertInfoPtr->subjectDNsize );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -