misc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
  2. /*
  3. * Copyright 2016 Red Hat, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "misc.h"
  18. #include <jose/b64.h>
  19. #include <string.h>
  20. #include <openssl/rand.h>
  21. size_t
  22. str2enum(const char *str, ...)
  23. {
  24. size_t i = 0;
  25. va_list ap;
  26. va_start(ap, str);
  27. for (const char *v = NULL; (v = va_arg(ap, const char *)); i++) {
  28. if (str && strcmp(str, v) == 0) {
  29. va_end(ap);
  30. return i;
  31. }
  32. }
  33. va_end(ap);
  34. return SIZE_MAX;
  35. }
  36. BIGNUM *
  37. bn_decode(const uint8_t buf[], size_t len)
  38. {
  39. return BN_bin2bn(buf, len, NULL);
  40. }
  41. BIGNUM *
  42. bn_decode_json(const json_t *json)
  43. {
  44. uint8_t *tmp = NULL;
  45. BIGNUM *bn = NULL;
  46. size_t len = 0;
  47. len = jose_b64_dec(json, NULL, 0);
  48. if (len == SIZE_MAX)
  49. return NULL;
  50. tmp = calloc(1, len);
  51. if (!tmp)
  52. return NULL;
  53. if (jose_b64_dec(json, tmp, len) != len) {
  54. free(tmp);
  55. return NULL;
  56. }
  57. bn = bn_decode(tmp, len);
  58. OPENSSL_cleanse(tmp, len);
  59. free(tmp);
  60. return bn;
  61. }
  62. bool
  63. bn_encode(const BIGNUM *bn, uint8_t buf[], size_t len)
  64. {
  65. int bytes = 0;
  66. if (!bn)
  67. return false;
  68. if (len == 0)
  69. len = BN_num_bytes(bn);
  70. bytes = BN_num_bytes(bn);
  71. if (bytes < 0 || bytes > (int) len)
  72. return false;
  73. memset(buf, 0, len);
  74. return BN_bn2bin(bn, &buf[len - bytes]) > 0;
  75. }
  76. json_t *
  77. bn_encode_json(const BIGNUM *bn, size_t len)
  78. {
  79. uint8_t *buf = NULL;
  80. json_t *out = NULL;
  81. if (!bn)
  82. return NULL;
  83. if (len == 0)
  84. len = BN_num_bytes(bn);
  85. if ((int) len < BN_num_bytes(bn))
  86. return NULL;
  87. buf = calloc(1, len);
  88. if (!buf)
  89. return NULL;
  90. if (bn_encode(bn, buf, len)) {
  91. out = jose_b64_enc(buf, len);
  92. OPENSSL_cleanse(buf, len);
  93. }
  94. free(buf);
  95. return out;
  96. }
  97. bool
  98. add_entity(json_t *root, json_t *obj, const char *plural, ...)
  99. {
  100. bool found = false;
  101. json_t *pl = NULL;
  102. va_list ap;
  103. pl = json_object_get(root, plural);
  104. if (pl) {
  105. if (!json_is_array(pl))
  106. return false;
  107. if (json_array_size(pl) == 0) {
  108. if (json_object_del(root, plural) == -1)
  109. return false;
  110. pl = NULL;
  111. }
  112. }
  113. va_start(ap, plural);
  114. for (const char *key; (key = va_arg(ap, const char *)); ) {
  115. if (json_object_get(root, key))
  116. found = true;
  117. }
  118. va_end(ap);
  119. /* If we have flattened format, migrate to general format. */
  120. if (found) {
  121. json_t *o = NULL;
  122. if (!pl) {
  123. pl = json_array();
  124. if (json_object_set_new(root, plural, pl) == -1)
  125. return false;
  126. }
  127. o = json_object();
  128. if (json_array_append_new(pl, o) == -1)
  129. return false;
  130. va_start(ap, plural);
  131. for (const char *key; (key = va_arg(ap, const char *)); ) {
  132. json_t *tmp = NULL;
  133. tmp = json_object_get(root, key);
  134. if (tmp) {
  135. if (json_object_set(o, key, tmp) == -1 ||
  136. json_object_del(root, key) == -1) {
  137. va_end(ap);
  138. return false;
  139. }
  140. }
  141. }
  142. va_end(ap);
  143. }
  144. /* If we have some signatures already, append to the array. */
  145. if (pl)
  146. return json_array_append(pl, obj) == 0;
  147. return json_object_update(root, obj) == 0;
  148. }
  149. static void __attribute__((constructor))
  150. constructor(void)
  151. {
  152. OpenSSL_add_all_algorithms();
  153. RAND_poll();
  154. }