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;
}