ULONG AnscX509CertGetKeyType ( void* raw_cert_data, ULONG raw_cert_size, PULONG cert_signing, PULONG cert_key_usage, PULONG cert_key_bits ) { PANSC_ASN1_CERTIFICATE pAsnCert = NULL; ULONG keyType = ANSC_CERT_keyType_rsa; ULONG keyUsage; /* decode the asn.1 certificate handle */ pAsnCert = (PANSC_ASN1_CERTIFICATE) anscGetCertHandle ( raw_cert_data, raw_cert_size ); if( pAsnCert == NULL) { goto EXIT; } if( pAsnCert->GetKeyType(pAsnCert) == PKI_RSA_KEY) { keyType = ANSC_CERT_keyType_rsa; *cert_signing = ANSC_CERT_signing_rsa; } else if( pAsnCert->GetKeyType(pAsnCert) == PKI_DSA_KEY) { keyType = ANSC_CERT_keyType_dsa; *cert_signing = ANSC_CERT_signing_dsa; } else { keyType = ANSC_CERT_keyType_diffieHellman; } *cert_key_bits = pAsnCert->GetKeyBits(pAsnCert); /* get the key usage; */ if( ANSC_STATUS_SUCCESS == pAsnCert->GetKeyUsage(pAsnCert, &keyUsage)) { if( keyUsage >= 0x0100) { *cert_key_usage |= ANSC_CERT_keyUsage_deciperOnly; } *cert_key_usage += keyUsage & 0x000000FF; } EXIT: anscFreeCertHandle((ANSC_HANDLE)pAsnCert); return keyType; }
/********************************************************************************* * * Utility functions * *********************************************************************************/ ANSC_X509_CERTIFICATE* AnscX509CertGetCertWrap ( void* raw_cert_data, ULONG raw_cert_size ) { ANSC_X509_CERTIFICATE* pX509Cert = NULL; PANSC_ASN1_CERTIFICATE pAsnCert = NULL; ULONG keyUsage = 0; ANSC_CRYPTO_HASH hash; /* decode the asn.1 certificate handle */ pAsnCert = (PANSC_ASN1_CERTIFICATE) anscGetCertHandle ( raw_cert_data, raw_cert_size ); if( pAsnCert == NULL) { goto EXIT; } /* create the X509 Certificate */ pX509Cert = (PANSC_X509_CERTIFICATE)AnscAllocateMemory(sizeof(ANSC_X509_CERTIFICATE)); if( pX509Cert == NULL) { goto EXIT; } /* init the pX509Cert */ pX509Cert->CertSize = raw_cert_size; pX509Cert->CertData = (PVOID)AnscAllocateMemory(raw_cert_size); if( pX509Cert->CertData != NULL) { AnscCopyMemory( pX509Cert->CertData, raw_cert_data, raw_cert_size); } pX509Cert->bSelfSigned = pAsnCert->IsSelfSigned(pAsnCert); if( pAsnCert->GetKeyType(pAsnCert) == PKI_RSA_KEY) { pX509Cert->Signing = ANSC_CERT_signing_rsa; pX509Cert->KeyType = ANSC_CERT_keyType_rsa; } else if( pAsnCert->GetKeyType(pAsnCert) == PKI_DSA_KEY) { pX509Cert->Signing = ANSC_CERT_signing_dsa; pX509Cert->KeyType = ANSC_CERT_keyType_dsa; } else { pX509Cert->KeyType = ANSC_CERT_keyType_diffieHellman; } /* get the key length */ pX509Cert->KeyBits = pAsnCert->GetKeyBits(pAsnCert); /* get the key usage; */ if( ANSC_STATUS_SUCCESS == pAsnCert->GetKeyUsage(pAsnCert, &keyUsage)) { /* the value has to be reversed */ pX509Cert->KeyUsage = 0; if( keyUsage >= 0x0100) { pX509Cert->KeyUsage += ANSC_CERT_keyUsage_deciperOnly; } keyUsage = keyUsage & 0x000000FF; if( keyUsage & 0x00000001) { pX509Cert->KeyUsage += 0x000000080; } if( keyUsage & 0x00000002) { pX509Cert->KeyUsage += 0x000000040; } if( keyUsage & 0x00000004) { pX509Cert->KeyUsage += 0x000000020; } if( keyUsage & 0x00000008) { pX509Cert->KeyUsage += 0x000000010; } if( keyUsage & 0x00000010) { pX509Cert->KeyUsage += 0x000000008; } if( keyUsage & 0x00000020) { pX509Cert->KeyUsage += 0x000000004; } if( keyUsage & 0x00000040) { pX509Cert->KeyUsage += 0x000000002; } if( keyUsage & 0x00000080) { pX509Cert->KeyUsage += 0x000000001; } } else { /* * For the old cert without KeyUsage extension, we assume it * has all the usages */ pX509Cert->KeyUsage = 0x000000FF; } /* get the md5 hash of the raw stream and set it as the CertID */ hash.Length = ANSC_MD5_OUTPUT_SIZE; hash.Length = AnscCryptoMd5Digest(raw_cert_data, raw_cert_size, &hash); AnscCopyMemory ( pX509Cert->CertID, hash.Value, hash.Length ); #if 1 if( pAsnCert->IsSelfSigned(pAsnCert)) { if(!pAsnCert->VerifySignature(pAsnCert, NULL)) { AnscTrace("Warning: Failed to verify the self-signed certificate.\n"); } } #endif EXIT: anscFreeCertHandle((ANSC_HANDLE)pAsnCert); return pX509Cert; }