k5der-include.patch 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. --- a/src/include/k5-der.h 2024-06-05 20:24:39.858675245 +0200
  2. +++ b/src/include/k5-der.h 2024-07-07 00:10:12.110510732 +0200
  3. @@ -0,0 +1,149 @@
  4. +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
  5. +/* include/k5-der.h - Distinguished Encoding Rules (DER) declarations */
  6. +/*
  7. + * Copyright (C) 2023 by the Massachusetts Institute of Technology.
  8. + * All rights reserved.
  9. + *
  10. + * Redistribution and use in source and binary forms, with or without
  11. + * modification, are permitted provided that the following conditions
  12. + * are met:
  13. + *
  14. + * * Redistributions of source code must retain the above copyright
  15. + * notice, this list of conditions and the following disclaimer.
  16. + *
  17. + * * Redistributions in binary form must reproduce the above copyright
  18. + * notice, this list of conditions and the following disclaimer in
  19. + * the documentation and/or other materials provided with the
  20. + * distribution.
  21. + *
  22. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  27. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  29. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  31. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  33. + * OF THE POSSIBILITY OF SUCH DAMAGE.
  34. + */
  35. +
  36. +/*
  37. + * Most ASN.1 encoding and decoding is done using the table-driven framework in
  38. + * libkrb5. When that is not an option, these helpers can be used to encode
  39. + * and decode simple types.
  40. + */
  41. +
  42. +#ifndef K5_DER_H
  43. +#define K5_DER_H
  44. +
  45. +#include <stdint.h>
  46. +#include <stdbool.h>
  47. +#include "k5-buf.h"
  48. +#include "k5-input.h"
  49. +
  50. +/* Return the number of bytes needed to encode len as a DER encoding length. */
  51. +static inline size_t
  52. +k5_der_len_len(size_t len)
  53. +{
  54. + size_t llen;
  55. +
  56. + if (len < 128)
  57. + return 1;
  58. + llen = 1;
  59. + while (len > 0) {
  60. + len >>= 8;
  61. + llen++;
  62. + }
  63. + return llen;
  64. +}
  65. +
  66. +/* Return the number of bytes needed to encode a DER value (with identifier
  67. + * byte and length) for a given contents length. */
  68. +static inline size_t
  69. +k5_der_value_len(size_t contents_len)
  70. +{
  71. + return 1 + k5_der_len_len(contents_len) + contents_len;
  72. +}
  73. +
  74. +/* Add a DER identifier byte (composed by the caller, including the ASN.1
  75. + * class, tag, and constructed bit) and length. */
  76. +static inline void
  77. +k5_der_add_taglen(struct k5buf *buf, uint8_t idbyte, size_t len)
  78. +{
  79. + uint8_t *p;
  80. + size_t llen = k5_der_len_len(len);
  81. +
  82. + p = k5_buf_get_space(buf, 1 + llen);
  83. + if (p == NULL)
  84. + return;
  85. + *p++ = idbyte;
  86. + if (len < 128) {
  87. + *p = len;
  88. + } else {
  89. + *p = 0x80 | (llen - 1);
  90. + /* Encode the length bytes backwards so the most significant byte is
  91. + * first. */
  92. + p += llen;
  93. + while (len > 0) {
  94. + *--p = len & 0xFF;
  95. + len >>= 8;
  96. + }
  97. + }
  98. +}
  99. +
  100. +/* Add a DER value (identifier byte, length, and contents). */
  101. +static inline void
  102. +k5_der_add_value(struct k5buf *buf, uint8_t idbyte, const void *contents,
  103. + size_t len)
  104. +{
  105. + k5_der_add_taglen(buf, idbyte, len);
  106. + k5_buf_add_len(buf, contents, len);
  107. +}
  108. +
  109. +/*
  110. + * If the next byte in in matches idbyte and the subsequent DER length is
  111. + * valid, advance in past the value, set *contents_out to the value contents,
  112. + * and return true. Otherwise return false. Only set an error on in if the
  113. + * next bytes matches idbyte but the ensuing length is invalid. contents_out
  114. + * may be aliased to in; it will only be written to on successful decoding of a
  115. + * value.
  116. + */
  117. +static inline bool
  118. +k5_der_get_value(struct k5input *in, uint8_t idbyte,
  119. + struct k5input *contents_out)
  120. +{
  121. + uint8_t lenbyte, i;
  122. + size_t len;
  123. + const void *bytes;
  124. +
  125. + /* Do nothing if in is empty or the next byte doesn't match idbyte. */
  126. + if (in->status || in->len == 0 || *in->ptr != idbyte)
  127. + return false;
  128. +
  129. + /* Advance past the identifier byte and decode the length. */
  130. + (void)k5_input_get_byte(in);
  131. + lenbyte = k5_input_get_byte(in);
  132. + if (lenbyte < 128) {
  133. + len = lenbyte;
  134. + } else {
  135. + len = 0;
  136. + for (i = 0; i < (lenbyte & 0x7F); i++) {
  137. + if (len > (SIZE_MAX >> 8)) {
  138. + k5_input_set_status(in, EOVERFLOW);
  139. + return false;
  140. + }
  141. + len = (len << 8) | k5_input_get_byte(in);
  142. + }
  143. + }
  144. +
  145. + bytes = k5_input_get_bytes(in, len);
  146. + if (bytes == NULL)
  147. + return false;
  148. + k5_input_init(contents_out, bytes, len);
  149. + return true;
  150. +}
  151. +
  152. +#endif /* K5_DER_H */