/* Benjamin DELPY `gentilkiwi` http://blog.gentilkiwi.com benjamin@gentilkiwi.com Licence : https://creativecommons.org/licenses/by/4.0/ */ #include "kull_m_asn1.h" ASN1module_t hASN1Module = NULL; ASN1encoding_t ASN1enc = NULL; ASN1decoding_t ASN1dec = NULL; void kull_m_asn1_BitStringFromULONG(BerElement * pBer, ULONG data) { BYTE flagBuffer[5] = {0}; *(PDWORD) (flagBuffer + 1) = _byteswap_ulong(data); ber_printf(pBer, "X", flagBuffer, sizeof(flagBuffer)); } void kull_m_asn1_GenTime(BerElement * pBer, PFILETIME localtime) { SYSTEMTIME st; char buffer[4 + 2 + 2 + 2 + 2 + 2 + 1 + 1]; if(FileTimeToSystemTime(localtime, &st)) if(sprintf_s(buffer, sizeof(buffer), "%04hu%02hu%02hu%02hu%02hu%02huZ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond) > 0) ber_printf(pBer, "to", DIRTY_ASN1_ID_GENERALIZED_TIME, buffer, sizeof(buffer) - 1); } void kull_m_asn1_GenString(BerElement * pBer, PCUNICODE_STRING String) { ANSI_STRING aString; if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&aString, String, TRUE))) { ber_printf(pBer, "to", DIRTY_ASN1_ID_GENERAL_STRING, aString.Buffer, aString.Length); RtlFreeAnsiString(&aString); } } static const ASN1GenericFun_t kull_m_asn1_encdecfreefntab[] = {NULL}; static const ASN1uint32_t kull_m_asn1_sizetab[] = {0}; BOOL kull_m_asn1_init() { BOOL status = FALSE; int ret; if(hASN1Module = ASN1_CreateModule(ASN1_THIS_VERSION, ASN1_BER_RULE_DER, ASN1FLAGS_NOASSERT, 1, kull_m_asn1_encdecfreefntab, kull_m_asn1_encdecfreefntab, (const ASN1FreeFun_t *) kull_m_asn1_encdecfreefntab, kull_m_asn1_sizetab, 'iwik')) { ret = ASN1_CreateEncoder(hASN1Module, &ASN1enc, NULL, 0, NULL); if(ASN1_FAILED(ret)) { PRINT_ERROR(L"ASN1_CreateEncoder: %i\n", ret); ASN1enc = NULL; } else { ret = ASN1_CreateDecoder(hASN1Module, &ASN1dec, NULL, 0, NULL); if(ASN1_FAILED(ret)) { PRINT_ERROR(L"ASN1_CreateDecoder: %i\n", ret); ASN1dec = NULL; } } } else PRINT_ERROR(L"ASN1_CreateModule\n"); status = hASN1Module && ASN1enc && ASN1dec; if(!status) kull_m_asn1_term(); return status; } void kull_m_asn1_term() { if(ASN1dec) { ASN1_CloseDecoder(ASN1dec); ASN1dec = NULL; } if(ASN1enc) { ASN1_CloseEncoder(ASN1enc); ASN1enc = NULL; } if(hASN1Module) { ASN1_CloseModule(hASN1Module); hASN1Module = NULL; } } BOOL kull_m_asn1_DotVal2Eoid(__in const ASN1char_t *dotOID, __out OssEncodedOID *encodedOID) { BOOL status = FALSE; if(ASN1enc && dotOID && encodedOID) { encodedOID->length = 0; encodedOID->value = NULL; status = ASN1BERDotVal2Eoid(ASN1enc, dotOID, encodedOID); } return status; } void kull_m_asn1_freeEnc(void *pBuf) { if(ASN1enc && pBuf) ASN1_FreeEncoded(ASN1enc, pBuf); } BOOL kull_m_asn1_Eoid2DotVal(__in const OssEncodedOID *encodedOID, __out ASN1char_t **dotOID) { BOOL status = FALSE; if(ASN1dec && encodedOID && dotOID) { *dotOID = NULL; status = ASN1BEREoid2DotVal(ASN1dec, encodedOID, dotOID); } return status; } void kull_m_asn1_freeDec(void *pBuf) { if(pBuf) ASN1Free(pBuf); }