static asn1_error_code asn1_encode_integer_internal(asn1buf *buf, asn1_intmax val, unsigned int *retlen) { asn1_error_code retval; unsigned int length = 0; long valcopy; int digit; valcopy = val; do { digit = (int) (valcopy&0xFF); retval = asn1buf_insert_octet(buf,(asn1_octet) digit); if (retval) return retval; length++; valcopy = valcopy >> 8; } while (valcopy != 0 && valcopy != ~0); if ((val > 0) && ((digit&0x80) == 0x80)) { /* make sure the high bit is */ retval = asn1buf_insert_octet(buf,0); /* of the proper signed-ness */ if (retval) return retval; length++; } else if ((val < 0) && ((digit&0x80) != 0x80)) { retval = asn1buf_insert_octet(buf,0xFF); if (retval) return retval; length++; } *retlen = length; return 0; }
asn1_error_code k5_asn1_encode_uint(asn1buf *buf, uintmax_t val, size_t *len_out) { asn1_error_code ret; size_t len = 0; uintmax_t valcopy; int digit; valcopy = val; do { digit = valcopy & 0xFF; ret = asn1buf_insert_octet(buf, digit); if (ret) return ret; len++; valcopy = valcopy >> 8; } while (valcopy != 0); if (digit & 0x80) { /* make sure the high bit is */ ret = asn1buf_insert_octet(buf, 0); /* of the proper signed-ness */ if (ret) return ret; len++; } *len_out = len; return 0; }
asn1_error_code k5_asn1_encode_int(asn1buf *buf, asn1_intmax val, size_t *len_out) { asn1_error_code ret; size_t len = 0; long valcopy; int digit; valcopy = val; do { digit = valcopy & 0xFF; ret = asn1buf_insert_octet(buf, digit); if (ret) return ret; len++; valcopy = valcopy >> 8; } while (valcopy != 0 && valcopy != ~0); if (val > 0 && (digit & 0x80) == 0x80) { /* make sure the high bit is */ ret = asn1buf_insert_octet(buf, 0); /* of the proper signed-ness */ if (ret) return ret; len++; } else if (val < 0 && (digit & 0x80) != 0x80) { ret = asn1buf_insert_octet(buf, 0xFF); if (ret) return ret; len++; } *len_out = len; return 0; }
asn1_error_code asn1_encode_unsigned_integer(asn1buf *buf, asn1_uintmax val, unsigned int *retlen) { asn1_error_code retval; unsigned int length = 0; unsigned int partlen; unsigned long valcopy; int digit; valcopy = val; do { digit = (int) (valcopy&0xFF); retval = asn1buf_insert_octet(buf,(asn1_octet) digit); if (retval) return retval; length++; valcopy = valcopy >> 8; } while (valcopy != 0); if (digit&0x80) { /* make sure the high bit is */ retval = asn1buf_insert_octet(buf,0); /* of the proper signed-ness */ if (retval) return retval; length++; } retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_INTEGER,length, &partlen); if (retval) return retval; length += partlen; *retlen = length; return 0; }
asn1_error_code asn1_make_id(asn1buf *buf, asn1_class asn1class, asn1_construction construction, asn1_tagnum tagnum, unsigned int *retlen) { asn1_error_code retval; if (tagnum < 31) { retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction | (asn1_octet)tagnum)); if (retval) return retval; *retlen = 1; } else { asn1_tagnum tagcopy = tagnum; int length = 0; retval = asn1buf_insert_octet(buf, (asn1_octet)(tagcopy&0x7F)); if (retval) return retval; tagcopy >>= 7; length++; for (; tagcopy != 0; tagcopy >>= 7) { retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(tagcopy&0x7F))); if (retval) return retval; length++; } retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction | 0x1F)); if (retval) return retval; length++; *retlen = length; } return 0; }
asn1_error_code asn1_make_length(asn1buf *buf, const unsigned int in_len, unsigned int *retlen) { asn1_error_code retval; if (in_len < 128) { retval = asn1buf_insert_octet(buf, (asn1_octet)(in_len&0x7F)); if (retval) return retval; *retlen = 1; } else { int in_copy=in_len, length=0; while (in_copy != 0) { retval = asn1buf_insert_octet(buf, (asn1_octet)(in_copy&0xFF)); if (retval) return retval; in_copy = in_copy >> 8; length++; } retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(length&0x7F))); if (retval) return retval; length++; *retlen = length; } return 0; }
asn1_error_code asn1_encode_null(asn1buf *buf, int *retlen) { asn1_error_code retval; retval = asn1buf_insert_octet(buf,0x00); if (retval) return retval; retval = asn1buf_insert_octet(buf,0x05); if (retval) return retval; *retlen = 2; return 0; }
asn1_error_code k5_asn1_encode_bool(asn1buf *buf, intmax_t val, size_t *len_out) { asn1_octet bval = val ? 0xFF : 0x00; *len_out = 1; return asn1buf_insert_octet(buf, bval); }
asn1_error_code k5_asn1_encode_bitstring(asn1buf *buf, unsigned char *const *val, size_t len, size_t *len_out) { asn1_error_code ret; ret = asn1buf_insert_octetstring(buf, len, *val); if (ret) return ret; *len_out = len + 1; return asn1buf_insert_octet(buf, '\0'); }
asn1_error_code asn1_encode_krb5_flags(asn1buf *buf, const krb5_flags val, unsigned int *retlen) { asn1_setup(); krb5_flags valcopy = val; int i; for(i=0; i<4; i++){ retval = asn1buf_insert_octet(buf,(asn1_octet) (valcopy&0xFF)); if(retval) return retval; valcopy >>= 8; } retval = asn1buf_insert_octet(buf,0); /* 0 padding bits */ if(retval) return retval; sum = 5; retval = asn1_make_tag(buf,UNIVERSAL,PRIMITIVE,ASN1_BITSTRING,sum, &length); if(retval) return retval; sum += length; *retlen = sum; return 0; }
asn1_error_code asn1_encode_bitstring(asn1buf *buf, unsigned int len, const void *val, unsigned int *retlen) { asn1_error_code retval; unsigned int length; retval = asn1buf_insert_octetstring(buf, len, val); if (retval) return retval; retval = asn1buf_insert_octet(buf, 0); if (retval) return retval; retval = asn1_make_tag(buf, UNIVERSAL, PRIMITIVE, ASN1_BITSTRING, len+1, &length); if (retval) return retval; *retlen = len + 1 + length; return 0; }
asn1_error_code asn1_encode_boolean(asn1buf *buf, asn1_intmax val, unsigned int *retlen) { asn1_error_code retval; unsigned int length = 0; unsigned int partlen = 1; asn1_octet bval; bval = val ? 0xFF : 0x00; retval = asn1buf_insert_octet(buf, bval); if (retval) return retval; length = partlen; retval = asn1_make_tag(buf, UNIVERSAL, PRIMITIVE, ASN1_BOOLEAN, length, &partlen); if (retval) return retval; length += partlen; *retlen = length; return 0; }
/* Encode a DER tag into buf with the tag parameters in t and the content * length len. Place the length of the encoded tag in *retlen. */ static asn1_error_code make_tag(asn1buf *buf, const taginfo *t, size_t len, size_t *retlen) { asn1_error_code ret; asn1_tagnum tag_copy; size_t sum = 0, length, len_copy; if (t->tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW; /* Encode the length of the content within the tag. */ if (len < 128) { ret = asn1buf_insert_octet(buf, len & 0x7F); if (ret) return ret; length = 1; } else { length = 0; for (len_copy = len; len_copy != 0; len_copy >>= 8) { ret = asn1buf_insert_octet(buf, len_copy & 0xFF); if (ret) return ret; length++; } ret = asn1buf_insert_octet(buf, 0x80 | (length & 0x7F)); if (ret) return ret; length++; } sum += length; /* Encode the tag and construction bit. */ if (t->tagnum < 31) { ret = asn1buf_insert_octet(buf, t->asn1class | t->construction | t->tagnum); if (ret) return ret; length = 1; } else { tag_copy = t->tagnum; length = 0; ret = asn1buf_insert_octet(buf, tag_copy & 0x7F); if (ret) return ret; tag_copy >>= 7; length++; for (; tag_copy != 0; tag_copy >>= 7) { ret = asn1buf_insert_octet(buf, 0x80 | (tag_copy & 0x7F)); if (ret) return ret; length++; } ret = asn1buf_insert_octet(buf, t->asn1class | t->construction | 0x1F); if (ret) return ret; length++; } sum += length; *retlen = sum; return 0; }