jws.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. /**
  18. * JSON Web Signature (RFC 7515)
  19. *
  20. * A JSON Web Signature (JWS) is a standard data format for expresing
  21. * cryptographic signatures in JSON. The signatures are produced using a JSON
  22. * Web Key (JWK).
  23. *
  24. * For example, to create a simple signature of a string using a JWK (error
  25. * handling omitted):
  26. *
  27. * json_t *sig(const char *str, const json_t *jwk) {
  28. * json_auto_t *jws = json_pack("{s:o}", "payload",
  29. * jose_b64_enc(str, strlen(str)));
  30. * jose_jws_sig(NULL, jws, NULL, jwk);
  31. * return json_incref(jws);
  32. * }
  33. *
  34. * Likewise, to verify this signature (again, error handling omitted):
  35. *
  36. * char *ver(const json_t *jws, const json_t *jwk) {
  37. * char *str = NULL;
  38. * size_t len = 0;
  39. *
  40. * if (!jose_jws_ver(NULL, jws, NULL, jwk))
  41. * return NULL;
  42. *
  43. * len = jose_b64_dec(json_object_get(jws, "payload"), NULL, 0);
  44. * str = calloc(1, len + 1);
  45. * jose_b64_dec(json_object_get(jws, "payload"), str, len);
  46. * return str;
  47. * }
  48. *
  49. * \defgroup jose_jws JWS
  50. * \see https://tools.ietf.org/html/rfc7515
  51. * @{
  52. */
  53. #pragma once
  54. #include "cfg.h"
  55. #include "io.h"
  56. #include <jansson.h>
  57. #include <stdbool.h>
  58. #include <stdint.h>
  59. /**
  60. * Merges the JOSE headers of a JWS signature object.
  61. *
  62. * \param sig A JWS signature object.
  63. * \return The newly allocated JOSE header.
  64. */
  65. json_t *
  66. jose_jws_hdr(const json_t *sig);
  67. /**
  68. * Creates one or more signatures in a JWS object.
  69. *
  70. * The JWS object (\p jws) must contain the "payload" property.
  71. *
  72. * All signatures created will be appended to the JWS specified by \p jws. If
  73. * the resulting JWS (\p jws) would contain only a single signature, the JWS
  74. * will be represented in Flattened JWS JSON Serialization Syntax. Otherwise,
  75. * it will be represented in General JWS JSON Serialization Syntax.
  76. *
  77. * If \p jwk contains a JWK, a single signature is created. In this case, \p jws
  78. * must contain either a JWS signature object template or NULL. You may specify
  79. * algorithms or other signature behaviors simply by specifying them in the JOSE
  80. * headers of the JWS signature object template as defined by RFC 7515. If a
  81. * required property is missing, sensible defaults will be used and inserted
  82. * into the JOSE headers; inferring them from the JWK (\p jwk) where possible.
  83. *
  84. * If \p jwk contains an array of JWKs or a JWKSet, multiple signatures are
  85. * created. In this case, the \p sig parameter must contain one of the
  86. * following values:
  87. *
  88. * 1. A JWS signature object template that will be used for all signatures.
  89. * In this case, a copy will be made for each signature and \p sig will
  90. * not be modified in any way.
  91. *
  92. * 2. An array of JWS signature object templates. Each template will be
  93. * used with its corresponding JWK from \p jwk. If the arrays in \p sig
  94. * and \p jwk are a different size, an error will occur.
  95. *
  96. * 3. NULL. This has the same effect as passing NULL for each separate key.
  97. *
  98. * \param cfg The configuration context (optional).
  99. * \param jws The JWS object.
  100. * \param sig The JWS signature object template(s) or NULL.
  101. * \param jwk The JWK(s) or JWKSet used for creating signatures.
  102. * \return On success, true. Otherwise, false.
  103. */
  104. bool
  105. jose_jws_sig(jose_cfg_t *cfg, json_t *jws, json_t *sig, const json_t *jwk);
  106. /**
  107. * Creates one or more signatures in a JWS object using streaming.
  108. *
  109. * This function behaves substantially like jose_jws_sig() except:
  110. *
  111. * The payload is not specified in the JWS (\p jws). Rather, the payload is
  112. * provided using the returned IO object. The input to the returned IO object
  113. * will not be internally Base64 encoded. So you may need to prepend the IO
  114. * chain with the result of jose_b64_enc_io() (depending on your situation).
  115. *
  116. * Likewise, the payload is not stored in the JWS object (\p jws). This allows
  117. * for detached payloads and decreases memory use for signatures over large
  118. * payloads. If you would like to attach the payload, it is your responsibility
  119. * to do so manually.
  120. *
  121. * \param cfg The configuration context (optional).
  122. * \param jws The JWS object.
  123. * \param sig The JWS signature object template(s) or NULL.
  124. * \param jwk The JWK(s) or JWKSet used for creating signatures.
  125. * \return The new IO object or NULL on error.
  126. */
  127. jose_io_t *
  128. jose_jws_sig_io(jose_cfg_t *cfg, json_t *jws, json_t *sig, const json_t *jwk);
  129. /**
  130. * Verifies signatures of one or more JWKs in a JWS object.
  131. *
  132. * The JWS object (\p jws) must contain the "payload" property.
  133. *
  134. * If a single JWK (\p jwk) is specified, the \p all parameter is ignored. In
  135. * this case, if you would like to verify a particular JWS signature object,
  136. * you may specify it using the \p sig parameter. Otherwise, you may simply
  137. * pass NULL to verify any of the JWS signature objects in the JWS object.
  138. *
  139. * If \p jwk contains an array of JWKs or a JWKSet, the \p all parameter
  140. * determines whether a valid signature is required for every JWK in order to
  141. * successfully validate the JWS. For example, if you set \p all to false this
  142. * function will succeed if a valid signature is found for any of the provided
  143. * JWKs. When using this multiple JWK signature mode, the \p sig parameter must
  144. * contain one of the following values:
  145. *
  146. * 1. A single JWS signature object to validate against all/any of the
  147. * provided JWKs.
  148. *
  149. * 2. An array of JWS signature objects. In this case, each JWS signature
  150. * object will be mapped to its corresponding JWK from \p jwk. If the
  151. * arrays in \p sig and \p jwk are a different size, an error will occur.
  152. *
  153. * 3. NULL. This has the same effect as passing NULL for each separate key.
  154. *
  155. * \param cfg The configuration context (optional).
  156. * \param jws The JWS object.
  157. * \param sig The JWS signature object(s) to verify or NULL.
  158. * \param jwk The JWK(s) or JWKSet used for verifying signatures.
  159. * \param all Whether or not to require validation of all JWKs.
  160. * \return On success, true. Otherwise, false.
  161. */
  162. bool
  163. jose_jws_ver(jose_cfg_t *cfg, const json_t *jws, const json_t *sig,
  164. const json_t *jwk, bool all);
  165. /**
  166. * Verifies signatures of one or more JWKs in a JWS object using streaming.
  167. *
  168. * This function behaves substantially like jose_jws_ver() except:
  169. *
  170. * The payload is not specified in the JWS (\p jws). Rather, the payload is
  171. * provided using the returned IO object. The input to the returned IO object
  172. * will not be internally Base64 encoded. So you may need to prepend the IO
  173. * chain with the result of jose_b64_enc_io() (depending on your situation).
  174. *
  175. * Final signature verification is delayed until \ref jose_io_t.done() returns.
  176. *
  177. * \param cfg The configuration context (optional).
  178. * \param jws The JWS object.
  179. * \param sig The JWS signature object(s) to verify or NULL.
  180. * \param jwk The JWK(s) or JWKSet used for verifying signatures.
  181. * \param all Whether or not to require validation of all JWKs.
  182. * \return The new IO object or NULL on error.
  183. */
  184. jose_io_t *
  185. jose_jws_ver_io(jose_cfg_t *cfg, const json_t *jws, const json_t *sig,
  186. const json_t *jwk, bool all);
  187. /** @} */