📄 comp_get.c
字号:
assert( ( name == NULL && nameMaxLength == 0 ) || \
( isWritePtr( name, nameMaxLength ) ) );
assert( isWritePtr( nameLength, sizeof( int ) ) );
assert( isReadPtr( encodedDn, encodedDnLength ) );
REQUIRES( ( name == NULL && nameMaxLength == 0 ) || \
( name != NULL && \
nameMaxLength > 0 && \
nameMaxLength <= MAX_INTLENGTH_SHORT ) );
REQUIRES( encodedDnLength > 0 && \
encodedDnLength < MAX_INTLENGTH_SHORT );
/* Clear return values */
if( name != NULL )
memset( name, 0, min( 16, nameMaxLength ) );
*nameLength = 0;
/* Look for a pseudonym */
status = extractDnComponent( encodedDn, encodedDnLength,
"oid.2.5.4.65=", 13, &startPos, &length );
if( cryptStatusOK( status ) && \
length > 0 && length <= nameMaxLength )
{
return( attributeCopyParams( name, nameMaxLength, nameLength,
encodedDn + startPos, length ) );
}
/* Look for givenName + surname */
status = extractDnComponent( encodedDn, encodedDnLength,
"G=", 2, &startPos, &length );
if( cryptStatusOK( status ) && \
length > 0 && length <= nameMaxLength )
{
char nameBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
int startPos2, length2;
status = extractDnComponent( encodedDn, encodedDnLength,
"S=", 2, &startPos2, &length2 );
if( cryptStatusOK( status ) && \
length2 > 0 && length + length2 <= nameMaxLength && \
length + length2 < MAX_ATTRIBUTE_SIZE )
{
memcpy( nameBuffer, encodedDn + startPos, length );
memcpy( nameBuffer + length, encodedDn + startPos2, length2 );
return( attributeCopyParams( name, nameMaxLength, nameLength,
nameBuffer, length + length2 ) );
}
}
/* We couldn't find anything useful */
return( CRYPT_ERROR_NOTFOUND );
}
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getHolderName( const CERT_INFO *certInfoPtr,
OUT_BUFFER_OPT( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
STREAM stream;
char encodedDnBuffer[ MAX_ATTRIBUTE_SIZE + 8 ];
int status;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* First we try for a CN */
status = getDNComponentValue( certInfoPtr->subjectName,
CRYPT_CERTINFO_COMMONNAME, certInfo,
certInfoMaxLength, certInfoLength );
if( cryptStatusOK( status ) )
return( status );
/* If that fails we try for either a pseudonym or givenName + surname.
Since these are part of the vast collection of oddball DN attributes
that aren't handled directly we have to get the encoded DN form and
look for them by OID (ugh) */
sMemOpen( &stream, encodedDnBuffer, MAX_ATTRIBUTE_SIZE );
status = writeDNstring( &stream, certInfoPtr->subjectName );
if( cryptStatusOK( status ) )
status = getNameFromDN( certInfo, certInfoMaxLength, certInfoLength,
encodedDnBuffer, stell( &stream ) );
sMemDisconnect( &stream );
if( cryptStatusOK( status ) )
return( status );
/* It's possible (although highly unlikely) that a certificate won't
have a usable CN-equivalent in some form, in which case we use the OU
instead. If that also fails we use the O. This gets a bit messy,
but duplicating the OU / O into the CN seems to be the best way to
handle this */
status = getDNComponentValue( certInfoPtr->subjectName,
CRYPT_CERTINFO_ORGANIZATIONALUNITNAME,
certInfo, certInfoMaxLength,
certInfoLength );
if( cryptStatusError( status ) )
status = getDNComponentValue( certInfoPtr->subjectName,
CRYPT_CERTINFO_ORGANIZATIONNAME,
certInfo, certInfoMaxLength,
certInfoLength );
return( status );
}
/* Get the certificate holder's URI, usually an email address but sometimes
also a URL */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getHolderURI( const CERT_INFO *certInfoPtr,
OUT_BUFFER( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
ATTRIBUTE_LIST *attributeListPtr;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* Find the subjectAltName, which contains the URI info */
attributeListPtr = findAttribute( certInfoPtr->attributes,
CRYPT_CERTINFO_SUBJECTALTNAME,
TRUE );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
/* There's altName data present try for an email address and if that
fails, a URL and an FQDN */
attributeListPtr = findAttributeField( attributeListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
CRYPT_CERTINFO_RFC822NAME );
if( attributeListPtr == NULL )
attributeListPtr = findAttributeField( attributeListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
CRYPT_CERTINFO_UNIFORMRESOURCEIDENTIFIER );
if( attributeListPtr == NULL )
attributeListPtr = findAttributeField( attributeListPtr,
CRYPT_CERTINFO_SUBJECTALTNAME,
CRYPT_CERTINFO_DNSNAME );
if( attributeListPtr == NULL )
return( CRYPT_ERROR_NOTFOUND );
return( getCertAttributeComponentData( attributeListPtr, certInfo,
certInfoMaxLength,
certInfoLength ) );
}
/* Get the ESSCertID for a certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
static int getESSCertID( INOUT CERT_INFO *certInfoPtr,
OUT_BUFFER( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
STREAM stream;
HASHFUNCTION_ATOMIC hashFunctionAtomic;
int hashSize, issuerSerialDataSize, status;
assert( isWritePtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
/* Get the hash algorithm information and hash the certificate to get
the certificate ID if necessary */
getHashAtomicParameters( CRYPT_ALGO_SHA1, &hashFunctionAtomic, &hashSize );
if( !certInfoPtr->certHashSet )
{
hashFunctionAtomic( certInfoPtr->certHash, KEYID_SIZE,
certInfoPtr->certificate,
certInfoPtr->certificateSize );
certInfoPtr->certHashSet = TRUE;
}
REQUIRES( certInfoPtr->cCertCert->serialNumber != NULL );
/* Write the ESSCertID:
ESSCertID ::= SEQUENCE {
certHash OCTET STRING SIZE(20),
issuerSerial SEQUENCE {
issuer SEQUENCE { [4] EXPLICIT Name },
serial INTEGER
}
} */
issuerSerialDataSize = ( int ) \
sizeofObject( sizeofObject( certInfoPtr->issuerDNsize ) ) + \
sizeofInteger( certInfoPtr->cCertCert->serialNumber,
certInfoPtr->cCertCert->serialNumberLength );
*certInfoLength = ( int ) \
sizeofObject( sizeofObject( hashSize ) + \
sizeofObject( issuerSerialDataSize ) );
if( certInfo == NULL )
return( CRYPT_OK );
if( *certInfoLength > certInfoMaxLength )
return( CRYPT_ERROR_OVERFLOW );
sMemOpen( &stream, certInfo, *certInfoLength );
writeSequence( &stream, sizeofObject( hashSize ) + \
sizeofObject( issuerSerialDataSize ) );
writeOctetString( &stream, certInfoPtr->certHash, hashSize, DEFAULT_TAG );
writeSequence( &stream, issuerSerialDataSize );
writeSequence( &stream, sizeofObject( certInfoPtr->issuerDNsize ) );
writeConstructed( &stream, certInfoPtr->issuerDNsize, 4 );
swrite( &stream, certInfoPtr->issuerDNptr, certInfoPtr->issuerDNsize );
status = writeInteger( &stream, certInfoPtr->cCertCert->serialNumber,
certInfoPtr->cCertCert->serialNumberLength,
DEFAULT_TAG );
sMemDisconnect( &stream );
ENSURES( cryptStatusOK( status ) );
return( status );
}
/* Encode PKI user information into the external format and return it */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 5 ) ) \
static int getPkiUserInfo( const CERT_INFO *certInfoPtr,
IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE certInfoType,
OUT_BUFFER( certInfoMaxLength, \
certInfoLength ) void *certInfo,
IN_LENGTH_SHORT_Z const int certInfoMaxLength,
OUT_LENGTH_SHORT_Z int *certInfoLength )
{
CERT_PKIUSER_INFO *certUserInfo = certInfoPtr->cCertUser;
char encUserInfo[ CRYPT_MAX_TEXTSIZE + 8 ];
BYTE userInfo[ 128 + 8 ], *userInfoPtr = userInfo;
int userInfoLength, encUserInfoLength, status;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
assert( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( isWritePtr( certInfo, certInfoMaxLength ) ) );
assert( isWritePtr( certInfoLength, sizeof( int ) ) );
REQUIRES( certInfoType == CRYPT_CERTINFO_PKIUSER_ID || \
certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD || \
certInfoType == CRYPT_CERTINFO_PKIUSER_REVPASSWORD );
REQUIRES( ( certInfo == NULL && certInfoMaxLength == 0 ) || \
( certInfo != NULL && \
certInfoMaxLength > 0 && \
certInfoMaxLength <= MAX_INTLENGTH_SHORT ) );
/* Clear return values */
if( certInfo != NULL )
memset( certInfo, 0, min( 16, certInfoMaxLength ) );
*certInfoLength = 0;
if( certInfoType == CRYPT_CERTINFO_PKIUSER_ID )
{
status = getCertAttributeComponent( certInfoPtr,
CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER,
userInfo, 128, &userInfoLength );
ENSURES( cryptStatusOK( status ) );
}
else
{
userInfoPtr = ( certInfoType == CRYPT_CERTINFO_PKIUSER_ISSUEPASSWORD ) ? \
certUserInfo->pkiIssuePW : certUserInfo->pkiRevPW;
userInfoLength = PKIUSER_AUTHENTICATOR_SIZE;
}
status = encodePKIUserValue( encUserInfo, CRYPT_MAX_TEXTSIZE,
&encUserInfoLength, userInfoPtr,
userInfoLength,
( certInfoType == \
CRYPT_CERTINFO_PKIUSER_ID ) ? 3 : 4 );
zeroise( userInfo, CRYPT_MAX_TEXTSIZE );
if( cryptStatusError( status ) )
return( status );
ENSURES( cryptStatusOK( \
decodePKIUserValue( userInfo, 128, &userInfoLength,
encUserInfo, encUserInfoLength ) ) );
status = attributeCopyParams( certInfo, certInfoMaxLength,
certInfoLength, encUserInfo,
encUserInfoLength );
zeroise( encUserInfo, CRYPT_MAX_TEXTSIZE );
return( status );
}
/* Get a pointer to the currently selected revocation/validity time */
CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 1 ) ) \
time_t *getRevocationTimePtr( const CERT_INFO *certInfoPtr )
{
time_t *timePtr;
assert( isReadPtr( certInfoPtr, sizeof( CERT_INFO ) ) );
/* If there's a specific validity/revocation entry selected, get its
invalidity/revocation time, otherwise if there are invalid/revoked
certificates present get the first certificate's
invalidity/revocation time, otherwise get the default
invalidity/revocation time */
if( certInfoPtr->type == CRYPT_CERTTYPE_RTCS_RESPONSE )
{
CERT_VAL_INFO *certValInfo = certInfoPtr->cCertVal;
timePtr = ( certValInfo->currentValidity != NULL ) ? \
&certValInfo->currentValidity->invalidityTime : \
( certValInfo->validityInfo != NULL ) ? \
&certValInfo->validityInfo->invalidityTime : NULL;
}
else
{
CERT_REV_INFO *certRevInfo = certInfoPtr->cCertRev;
timePtr = ( certRevInfo->currentRevocation != NULL ) ? \
&certRevInfo->currentRevocation->revocationTime : \
( certRevInfo->revocations != NULL ) ? \
&certRevInfo->revocations->revocationTime : \
( certRevInfo->revocationTime ) ? \
&certRevInfo->revocationTime : NULL;
}
return( timePtr );
}
/* Create a copy of a certificate object for external use. This is used
principally to sanitise internal certificate objects, for example if
they're attached to a private key or internal-use only. Since the object
can be either a standalone certificate or a complete certificate chain we
have to process it somewhat indirectly rather than just instantiating a
new certificate from the encoded certificate data.
It's also used to convert to/from data-only certificates, for example to
convert from a stored data-only certificate to a full certificate capable
of being used for signature checking, this is easier than trying to
retroactively attach a public-key context to a data-only certificate */
CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int getCertCopy( const CERT_INFO *certInfoPtr,
OUT_HANDLE_OPT CRYPT_CERTIFICATE *iCertCopy,
const BOOLEAN isDataOnlyCert )
{
const CRYPT_CERTFORMAT_TYPE formatType = \
( certInfoPtr->type == CRYPT_CERTTYPE_CERTIFICATE ) ? \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -