📄 certwr.c
字号:
/* If it's an RTCS response, prepare the cert status list entries
prior to encoding them */
status = prepareCertStatusEntries( subjectCertInfoPtr->revocations,
subjectCertInfoPtr->revocationTime,
&subjectCertInfoPtr->currentRevocation,
&subjectCertInfoPtr->errorLocus,
&subjectCertInfoPtr->errorType );
if( cryptStatusError( status ) )
return( status );
}
if( type == CRYPT_CERTTYPE_CRL || type == CRYPT_CERTTYPE_OCSP_RESPONSE )
{
/* If it's a CRL or OCSP response, prepare the revocation list
entries prior to encoding them */
status = prepareRevocationEntries( subjectCertInfoPtr->revocations,
subjectCertInfoPtr->revocationTime,
&subjectCertInfoPtr->currentRevocation,
&subjectCertInfoPtr->errorLocus,
&subjectCertInfoPtr->errorType );
if( cryptStatusError( status ) )
return( status );
}
/* Now that we've set up the attributes, perform the remainder of the
checks. Because RTCS is actually a CMS standard rather than PKIX,
the RTCS attributes are CMS rather than certificate attributes */
status = checkAttributes( ( type == CRYPT_CERTTYPE_RTCS_REQUEST ) ? \
ATTRIBUTE_CMS : ATTRIBUTE_CERTIFICATE,
subjectCertInfoPtr->attributes,
&subjectCertInfoPtr->errorLocus,
&subjectCertInfoPtr->errorType );
if( cryptStatusOK( status ) )
{
status = checkCert( subjectCertInfoPtr, issuerCertInfoPtr, FALSE,
&subjectCertInfoPtr->errorLocus,
&subjectCertInfoPtr->errorType );
if( cryptStatusOK( status ) )
subjectCertInfoPtr->maxCheckLevel = CRYPT_COMPLIANCELEVEL_PKIX_FULL;
}
return( status );
}
/****************************************************************************
* *
* Write a Certificate Object *
* *
****************************************************************************/
/* Write certificate information:
CertificateInfo ::= SEQUENCE {
version [ 0 ] EXPLICIT INTEGER DEFAULT(0),
serialNumber INTEGER,
signature AlgorithmIdentifier,
issuer Name
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
extensions [ 3 ] Extensions OPTIONAL
} */
static int writeCertInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
int length, extensionSize, status;
/* Perform any necessary pre-encoding steps */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_CERTIFICATE );
if( cryptStatusError( status ) )
return( status );
}
/* Determine how the issuer name will be encoded */
subjectCertInfoPtr->issuerDNsize = \
( issuerCertInfoPtr->subjectDNptr != NULL ) ? \
issuerCertInfoPtr->subjectDNsize : \
sizeofDN( subjectCertInfoPtr->issuerName );
subjectCertInfoPtr->subjectDNsize = \
sizeofDN( subjectCertInfoPtr->subjectName );
/* Determine the size of the certificate information */
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
length = sizeofInteger( subjectCertInfoPtr->serialNumber,
subjectCertInfoPtr->serialNumberLength ) + \
sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
ALGOID_FLAG_ALGOID_ONLY ) + \
subjectCertInfoPtr->issuerDNsize + \
sizeofObject( sizeofUTCTime() * 2 ) + \
subjectCertInfoPtr->subjectDNsize + \
subjectCertInfoPtr->publicKeyInfoSize;
if( extensionSize > 0 )
length += ( int ) \
sizeofObject( sizeofShortInteger( X509VERSION_3 ) ) + \
sizeofObject( sizeofObject( extensionSize ) );
/* Write the outer SEQUENCE wrapper */
writeSequence( stream, length );
/* If there are extensions present, mark this as a v3 certificate */
if( extensionSize )
{
writeConstructed( stream, sizeofShortInteger( X509VERSION_3 ),
CTAG_CE_VERSION );
writeShortInteger( stream, X509VERSION_3, DEFAULT_TAG );
}
/* Write the serial number and signature algorithm identifier */
writeInteger( stream, subjectCertInfoPtr->serialNumber,
subjectCertInfoPtr->serialNumberLength, DEFAULT_TAG );
status = writeContextAlgoID( stream, iIssuerCryptContext, CRYPT_ALGO_SHA,
ALGOID_FLAG_ALGOID_ONLY );
if( cryptStatusError( status ) )
return( status );
/* Write the issuer name, validity period, subject name, and public key
information */
if( issuerCertInfoPtr->subjectDNptr != NULL )
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
} */
static int writeAttributeCertInfo( STREAM *stream,
CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
int length, extensionSize, issuerNameSize, status;
/* Perform any necessary pre-encoding steps */
if( sIsNullStream( stream ) )
{
status = preEncodeCertificate( subjectCertInfoPtr, issuerCertInfoPtr,
CRYPT_CERTTYPE_ATTRIBUTE_CERT );
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 );
length = ( int ) sizeofObject( sizeofDN( subjectCertInfoPtr->subjectName ) ) + \
issuerNameSize + \
sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
ALGOID_FLAG_ALGOID_ONLY ) + \
sizeofInteger( subjectCertInfoPtr->serialNumber,
subjectCertInfoPtr->serialNumberLength ) + \
sizeofObject( sizeofUTCTime() * 2 ) + \
sizeofObject( 0 ) + \
( extensionSize ? ( 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 )
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, CRYPT_ALGO_SHA,
ALGOID_FLAG_ALGOID_ONLY );
writeInteger( stream, subjectCertInfoPtr->serialNumber,
subjectCertInfoPtr->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 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -