static int s_der_write_tlv()

in source/der.c [113:192]


static int s_der_write_tlv(struct der_tlv *tlv, struct aws_byte_buf *buf) {
    if (!aws_byte_buf_write_u8(buf, tlv->tag)) {
        return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
    }
    uint32_t len = s_encoded_len(tlv);
    if (len > UINT16_MAX) {
        /* write the high bit plus 4 byte length */
        if (!aws_byte_buf_write_u8(buf, 0x84)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
        if (!aws_byte_buf_write_be32(buf, len)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
    } else if (len > UINT8_MAX) {
        /* write the high bit plus 2 byte length */
        if (!aws_byte_buf_write_u8(buf, 0x82)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
        if (!aws_byte_buf_write_be16(buf, (uint16_t)len)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
    } else if (len > INT8_MAX) {
        /* Write the high bit + 1 byte length */
        if (!aws_byte_buf_write_u8(buf, 0x81)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
        if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
    } else {
        if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) {
            return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
        }
    }

    switch (tlv->tag) {
        case AWS_DER_INTEGER: {
            /* if the first byte has the sign bit set, insert an extra 0x00 byte to indicate unsigned */
            uint8_t first_byte = tlv->value[0];
            if (first_byte & 0x80) {
                if (!aws_byte_buf_write_u8(buf, 0)) {
                    return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
                }
            }
            if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) {
                return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
            }
        } break;
        case AWS_DER_BOOLEAN:
            if (!aws_byte_buf_write_u8(buf, (*tlv->value) ? 0xff : 0x00)) {
                return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
            }
            break;
        case AWS_DER_BIT_STRING:
            /* Write that there are 0 skipped bits */
            if (!aws_byte_buf_write_u8(buf, 0)) {
                return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
            }
            /* FALLTHROUGH */
        case AWS_DER_BMPString:
        case AWS_DER_IA5String:
        case AWS_DER_PrintableString:
        case AWS_DER_UTF8_STRING:
        case AWS_DER_OBJECT_IDENTIFIER:
        case AWS_DER_OCTET_STRING:
        case AWS_DER_SEQUENCE:
        case AWS_DER_SET:
            if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) {
                return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE);
            }
            break;
        case AWS_DER_NULL:
            /* No value bytes */
            break;
        default:
            return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE);
    }

    return AWS_OP_SUCCESS;
}