📄 certwr.c
字号:
certID CertID,
extensions [0] EXPLICIT Extensions OPTIONAL
}
Entry ::= SEQUENCE { -- Response
certID CertID,
certStatus CHOICE { [0] ..., [1] ..., [2] ... },
thisUpdate GeneralizedTime,
extensions [1] EXPLICIT Extensions OPTIONAL
}
CertID ::= SEQUENCE {
hashAlgo AlgorithmIdentifier,
iNameHash OCTET STRING, -- Hash of issuerName
iKeyHash OCTET STRING, -- Hash of issuer SPKI w/o tag+len
serialNo INTEGER
}
or iAndSerial [0] EXPLICIT IssuerAndSerialNumber
or certificate [1] EXPLICIT Certificate
or certHash [2] EXPLICIT OCTET STRING */
static int sizeofOCSPentry( REVOCATION_INFO *ocspEntry,
const BOOLEAN isRequest )
{
const int idSize = ( ocspEntry->type == CRYPT_ATTRIBUTE_NONE ) ? \
ocspEntry->dataLength : \
( int ) sizeofObject( sizeofObject( ocspEntry->dataLength ) );
int certStatusSize = 0;
/* Remember the encoded attribute size for later when we write the
attributes */
ocspEntry->attributeSize = sizeofAttributes( ocspEntry->attributes );
/* Determine the size of the cert status field */
if( !isRequest )
certStatusSize = ( ocspEntry->status != CRYPT_OCSPSTATUS_REVOKED ) ? \
sizeofNull() : ( int ) sizeofObject( sizeofGeneralizedTime() );
return( ( int ) sizeofObject( idSize + \
( isRequest ? 0 : sizeofGeneralizedTime() ) + \
certStatusSize + \
( ( ocspEntry->attributeSize ) ? \
( int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) ) );
}
static int writeOCSPentry( STREAM *stream, const REVOCATION_INFO *ocspEntry,
const time_t entryTime, const BOOLEAN isRequest )
{
const int idSize = ( ocspEntry->type == CRYPT_ATTRIBUTE_NONE ) ? \
ocspEntry->dataLength : \
( int ) sizeofObject( sizeofObject( ocspEntry->dataLength ) );
int certStatusSize = 0;
/* Determine the size of the cert status field */
if( !isRequest )
certStatusSize = ( ocspEntry->status != CRYPT_OCSPSTATUS_REVOKED ) ? \
sizeofNull() : ( int ) sizeofObject( sizeofGeneralizedTime() );
/* Write the OCSP entry */
writeSequence( stream, idSize + \
( isRequest ? 0 : sizeofGeneralizedTime() ) + \
certStatusSize + \
( ( ocspEntry->attributeSize ) ? \
( int ) sizeofObject( ocspEntry->attributeSize ) : 0 ) );
if( ocspEntry->type == CRYPT_ATTRIBUTE_NONE )
swrite( stream, ocspEntry->data, ocspEntry->dataLength );
else
{
writeConstructed( stream, sizeofObject( ocspEntry->dataLength ),
OCSP_IDTYPE_CERTHASH );
writeOctetString( stream, ocspEntry->data, ocspEntry->dataLength,
DEFAULT_TAG );
}
if( !isRequest )
{
/* Write the cert status */
if( ocspEntry->status == CRYPT_OCSPSTATUS_REVOKED )
{
writeConstructed( stream, sizeofGeneralizedTime(),
CRYPT_OCSPSTATUS_REVOKED );
writeGeneralizedTime( stream, ocspEntry->revocationTime,
DEFAULT_TAG );
}
else
writeNull( stream, ocspEntry->status );
/* Write the current update time (which should be the current time).
Since new status information is always available, we don't write
a nextUpdate time */
writeGeneralizedTime( stream, entryTime, DEFAULT_TAG );
}
/* Write the per-entry extensions if necessary. Since these are per-
entry extensions we write them as CRYPT_CERTTYPE_NONE rather than
CRYPT_CERTTYPE_OCSP to make sure they're processed as required */
if( ocspEntry->attributeSize )
writeAttributes( stream, ocspEntry->attributes, CRYPT_CERTTYPE_NONE,
ocspEntry->attributeSize );
return( sGetStatus( stream ) );
}
/****************************************************************************
* *
* Write a Certificate Object *
* *
****************************************************************************/
/* Write certificate information:
CertificateInfo ::= SEQUENCE {
version [ 0 ] INTEGER DEFAULT(0),
serialNumber INTEGER,
signature AlgorithmIdentifier,
issuer Name
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
extensions [ 3 ] Extensions OPTIONAL
}
version is set to 2 if any extensions are present */
int writeCertInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
RESOURCE_DATA msgData;
int length, pubKeyDataSize, 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 */
setResourceData( &msgData, NULL, 0 );
status = krnlSendMessage( subjectCertInfoPtr->iCryptContext,
RESOURCE_IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
if( cryptStatusError( status ) )
return( status );
pubKeyDataSize = msgData.length;
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
length = ( extensionSize ? ( int ) sizeofObject(
sizeofShortInteger( X509VERSION_3 ) ) : 0 ) +
sizeofInteger( subjectCertInfoPtr->serialNumber,
subjectCertInfoPtr->serialNumberLength ) +
sizeofContextAlgoID( iIssuerCryptContext, CRYPT_ALGO_SHA,
ALGOID_FLAG_ALGOID_ONLY ) +
subjectCertInfoPtr->issuerDNsize +
( int ) sizeofObject( sizeofUTCTime() * 2 ) +
subjectCertInfoPtr->subjectDNsize + pubKeyDataSize +
( extensionSize ? \
( int ) sizeofObject( sizeofObject( extensionSize ) ) : 0 );
/* Write the outer SEQUENCE wrapper */
writeSequence( stream, length );
/* If there are extensions present, mark this as a v3 certificate */
if( extensionSize )
{
writeCtag( stream, CTAG_CE_VERSION );
writeLength( stream, sizeofShortInteger( X509VERSION_3 ) );
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, and subject name */
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( cryptStatusError( status ) )
return( status );
/* Write the public key information */
if( !sIsNullStream( stream ) )
{
setResourceData( &msgData, sMemBufPtr( stream ), pubKeyDataSize );
status = krnlSendMessage( subjectCertInfoPtr->iCryptContext,
RESOURCE_IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
if( cryptStatusError( status ) )
return( status );
}
sSkip( stream, pubKeyDataSize );
/* Write the extensions if necessary */
if( extensionSize )
writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_CERTIFICATE, extensionSize );
return( sGetStatus( stream ) );
}
/* 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
} */
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 ) +
( int ) sizeofObject( sizeofUTCTime() * 2 ) +
( int ) sizeofObject( 0 ) +
( extensionSize ? ( int ) sizeofObject( extensionSize ) : 0 );
/* Write the outer SEQUENCE wrapper */
writeSequence( stream, length );
/* Write the owner and issuer name */
writeCtag( stream, CTAG_AC_ENTITYNAME );
writeLength( stream, sizeofDN( subjectCertInfoPtr->subjectName ) );
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 */
writeSequence( stream, 0 );
/* Write the extensions if necessary */
if( extensionSize )
writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_ATTRIBUTE_CERT, extensionSize );
return( sGetStatus( stream ) );
}
/* Write certificate request information:
CertificationRequestInfo ::= SEQUENCE {
version INTEGER (0),
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
attributes [ 0 ] SET OF Attribute
}
Attributes are omitted if there are no extensions present and
CRYPT_OPTION_CERT_PKCS10ALT is set to TRUE. 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 */
int writeCertRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
{
RESOURCE_DATA msgData;
int useAltEncoding, length, pubKeyDataSize, 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 */
krnlSendMessage( subjectCertInfoPtr->ownerHandle,
RESOURCE_IMESSAGE_GETATTRIBUTE, &useAltEncoding,
CRYPT_OPTION_CERT_PKCS10ALT );
setResourceData( &msgData, NULL, 0 );
status = krnlSendMessage( subjectCertInfoPtr->iCryptContext,
RESOURCE_IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
if( cryptStatusError( status ) )
return( status );
pubKeyDataSize = msgData.length;
extensionSize = sizeofAttributes( subjectCertInfoPtr->attributes );
length = sizeofShortInteger( 0 ) +
sizeofDN( subjectCertInfoPtr->subjectName ) + pubKeyDataSize;
if( extensionSize )
length += ( int ) sizeofObject( sizeofObject( 11 + /* PKCS #9 OID size */
( int ) sizeofObject( sizeofObject( extensionSize ) ) ) );
else
if( !useAltEncoding )
length += ( int ) sizeofObject( 0 );
/* Write the header, version number, DN, and public key */
writeSequence( stream, length );
writeShortInteger( stream, 0, DEFAULT_TAG );
writeDN( stream, subjectCertInfoPtr->subjectName, DEFAULT_TAG );
if( !sIsNullStream( stream ) )
{
setResourceData( &msgData, sMemBufPtr( stream ), pubKeyDataSize );
status = krnlSendMessage( subjectCertInfoPtr->iCryptContext,
RESOURCE_IMESSAGE_GETATTRIBUTE_S,
&msgData, CRYPT_IATTRIBUTE_PUBLICKEY );
if( cryptStatusError( status ) )
return( status );
}
sSkip( stream, pubKeyDataSize );
/* Write the attributes */
if( extensionSize )
{
writeCtag( stream, CTAG_CR_ATTRIBUTES );
writeLength( stream, ( int ) sizeofObject( 11 + /* PKCS #9 OID size */
( int ) sizeofObject( sizeofObject( extensionSize ) ) ) );
writeAttributes( stream, subjectCertInfoPtr->attributes,
CRYPT_CERTTYPE_CERTREQUEST, extensionSize );
}
else
/* If there are no attributes and we're not using the PKCS #10
alternative encoding, write an (erroneous) zero-length field */
if( !useAltEncoding )
{
writeCtag( stream, CTAG_CR_ATTRIBUTES );
writeLength( stream, 0 );
}
return( sGetStatus( stream ) );
}
/* 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
}
} */
int writeCRMFRequestInfo( STREAM *stream, CERT_INFO *subjectCertInfoPtr,
const CERT_INFO *issuerCertInfoPtr,
const CRYPT_CONTEXT iIssuerCryptContext )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -