const uint8_t *
ccder_decode_constructed_tl(ccder_tag expected_tag, const uint8_t **body_end,
                            const uint8_t *der, const uint8_t *der_end) {
    size_t len;
    der = ccder_decode_tl(expected_tag, &len, der, der_end);
    *body_end = der + len;
    return der;
}
Пример #2
0
const uint8_t *
ccder_decode_oid(ccoid_t *oidp,
                                const uint8_t *der, const uint8_t *der_end) {
    size_t len;
    const uint8_t *body = ccder_decode_tl(CCDER_OBJECT_IDENTIFIER, &len,
                                          der, der_end);
    if (body) {
        oidp->oid = der;
        return body + len;
    }

    return NULL;
}
static const uint8_t *der_expect_SecAsn1Oid(const SecAsn1Oid* secasn_oid, const uint8_t *der, const uint8_t *der_end)
{
    size_t len = 0;
    der = ccder_decode_tl(CCDER_OBJECT_IDENTIFIER, &len,
                                          der, der_end);

    if (secasn_oid->Length != len || memcmp(secasn_oid->Data, der, len) != 0)
        der = NULL;
    else
        der += len;

    return der;
}
static const uint8_t* der_decode_bool(bool *value, const uint8_t *der, const uint8_t *der_end) {
    size_t payload_size = 0;
    
    der = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
    
    if (payload_size != 1) {
        der = NULL;
    }
    
    if (der != NULL) {
        *value = (*der != 0);
        der++;
    }

    return der;
}
Пример #5
0
const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;
    
    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);
    
    if (NULL == payload || (der_end - payload) < 1 || payload_size != 1) {
        return NULL;
    }
    
    if (boolean)
        *boolean = (*payload != 0);
    
    return payload + payload_size;
}
const uint8_t* der_decode_number(CFAllocatorRef allocator, CFOptionFlags mutability,
                                 CFNumberRef* number, CFErrorRef *error,
                                 const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;

    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_INTEGER, &payload_size, der, der_end);

    if (NULL == payload || (der_end - payload) < payload_size) {
        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown number encoding"), NULL, error);
        return NULL;
    }
    if (payload_size > sizeof(long long)) {
        SecCFDERCreateError(kSecDERErrorUnsupportedNumberType, CFSTR("Number too large"), NULL, error);
        return NULL;

    }

    long long value = 0;

    if (payload_size > 0) {
        if ((*payload & 0x80) == 0x80)
            value = -1; // Negative integers fill with 1s so we end up negative.
        
        const uint8_t* const payload_end = payload + payload_size;
        
        for (const uint8_t *payload_byte = payload;
             payload_byte < payload_end;
             ++payload_byte) {
            value <<= 8;
            value |= *payload_byte;
        }
    }

    *number = CFNumberCreate(allocator, kCFNumberLongLongType, &value);

    if (*number == NULL) {
        SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("Number allocation failed"), NULL, error);
        return NULL;
    }
    
    return payload + payload_size;
}
Пример #7
0
const uint8_t *
ccder_decode_bitstring(const uint8_t **bit_string,
                       size_t *bit_length, const uint8_t *der, const uint8_t *der_end) {
    size_t len;
    const uint8_t *content = ccder_decode_tl(CCDER_BIT_STRING, &len,
                             der, der_end);
    if (content) {
        if ((len >= 1) && (((len - 1) * 8) >= (*content))) {
            *bit_length = ((len - 1) * 8) - *content;
        }
        else {
            *bit_length = 0;
        }
        *bit_string = content + 1;
        return content + len;
    }
    return NULL;
}
Пример #8
0
const uint8_t* der_decode_null(CFAllocatorRef allocator, CFOptionFlags mutability,
                                  CFNullRef* nul, CFErrorRef *error,
                                  const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;
	
    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_NULL, &payload_size, der, der_end);
	
	if (NULL == payload || payload_size != 0) {
        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown null encoding"), NULL, error);
        return NULL;
    }
	
    *nul = kCFNull;
	
    return payload + payload_size;
}
const uint8_t* der_decode_boolean(CFAllocatorRef allocator, CFOptionFlags mutability,
                                  CFBooleanRef* boolean, CFErrorRef *error,
                                  const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;

    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end);

    if (NULL == payload || (der_end - payload) < payload_size || payload_size != 1) {
        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown boolean encoding"), NULL, error);
        return NULL;
    }

    *boolean = *payload ? kCFBooleanTrue : kCFBooleanFalse;

    return payload + payload_size;
}
static const uint8_t *der_decode_pbkdf2_params(size_t *saltLen, const uint8_t **salt,
                                               unsigned long *iterationCount,
                                               unsigned long *keyLength,
                                               const uint8_t *der, const uint8_t *der_end)
{
    const uint8_t * body_end = NULL;
    der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &body_end, der, der_end);

    if (body_end != der_end)
        der = NULL;

    size_t salt_size = 0;
    const uint8_t *salt_bytes = NULL;

    der = ccder_decode_tl(CCDER_OCTET_STRING, &salt_size, der, body_end);
    salt_bytes = der;
    der += salt_size;

    uint64_t iteration_count = 0;
    uint64_t key_len = 0;
    der = ccder_decode_uint64(&iteration_count, der, body_end);
    if (iteration_count > UINT32_MAX)
        der = NULL;

    der = ccder_decode_uint64(&key_len, der, body_end);
    if (key_len > UINT32_MAX)
        der = NULL;

    der = der_expect_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1, der, body_end);

    if (der) {
        if (salt)
            *salt = salt_bytes;
        if (saltLen)
            *saltLen = salt_size;
        if (iterationCount)
            *iterationCount = (unsigned long)iteration_count;
        if (keyLength)
            *keyLength = (unsigned long) key_len;
    }

    return der;
}
Пример #11
0
const uint8_t* der_decode_string(CFAllocatorRef allocator, CFOptionFlags mutability,
                                 CFStringRef* string, CFErrorRef *error,
                                 const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;

    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_UTF8_STRING, &payload_size, der, der_end);

    if (NULL == payload || (ssize_t) (der_end - payload) < (ssize_t) payload_size){
        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown string encoding"), NULL, error);
        return NULL;
    }

    *string = CFStringCreateWithBytes(allocator, payload, payload_size, kCFStringEncodingUTF8, false);

    if (NULL == *string) {
        SecCFDERCreateError(kSecDERErrorAllocationFailure, CFSTR("String allocation failed"), NULL, error);
        return NULL;
    }

    return payload + payload_size;
}
const uint8_t* der_decode_data(CFAllocatorRef allocator, CFOptionFlags mutability,
                               CFDataRef* data, CFErrorRef *error,
                               const uint8_t* der, const uint8_t *der_end)
{
    if (NULL == der)
        return NULL;

    size_t payload_size = 0;
    const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end);

    if (NULL == payload || (der_end - payload) < payload_size) {
        SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error);
        return NULL;
    }

    *data = CFDataCreate(allocator, payload, payload_size);

    if (NULL == *data) {
        SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error);
        return NULL;
    }

    return payload + payload_size;
}