You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mi...@apache.org on 2018/09/01 19:42:30 UTC
svn commit: r1839838 [1/2] - in /apr/apr/trunk: include/apr_jose.h
test/testjose.c
Author: minfrin
Date: Sat Sep 1 19:42:30 2018
New Revision: 1839838
URL: http://svn.apache.org/viewvc?rev=1839838&view=rev
Log:
Add header and tests for JOSE support. I need sleep.
Added:
apr/apr/trunk/include/apr_jose.h (with props)
apr/apr/trunk/test/testjose.c (with props)
Added: apr/apr/trunk/include/apr_jose.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_jose.h?rev=1839838&view=auto
==============================================================================
--- apr/apr/trunk/include/apr_jose.h (added)
+++ apr/apr/trunk/include/apr_jose.h Sat Sep 1 19:42:30 2018
@@ -0,0 +1,1139 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file apr_jose.h
+ * @brief APR-UTIL JSON Object Signing and Encryption Library
+ */
+#ifndef APR_JOSE_H
+#define APR_JOSE_H
+
+/**
+ * @defgroup APR_Util_JOSE JSON Object Signing and Encryption
+ * @ingroup APR_Util
+ * @{
+ *
+ * The JOSE (JSON Object Signing and Encryption) library allows the encoding
+ * and decoding of JWS (JSON Web Signature), JWE (JSON Web Encryption), JWK
+ * (JSON Web Key) and JWT (JSON Web Token) objects, encoded using compact
+ * encoding, JSON encoding, or flattened JSON encoding.
+ *
+ * The following RFCs are supported:
+ *
+ * - https://tools.ietf.org/html/rfc7515 - JSON Web Signature (JWS)
+ * - https://tools.ietf.org/html/rfc7516 - JSON Web Encryption (JWE)
+ * - https://tools.ietf.org/html/rfc7517 - JSON Web Key (JWK)
+ * - https://tools.ietf.org/html/rfc7519 - JSON Web Token (JWT)
+ *
+ * Encryption, decryption, signing and verification are implemented as
+ * callbacks to the caller's specification, and are not included.
+ *
+ * When decrypting or verifying, the caller MUST verify that the 'alg'
+ * algorithm parameter in the JOSE message matches the algorithm expected
+ * by the implementation.
+ *
+ * It is recommended that the apr_crypto library be used to implement the
+ * callbacks, however an alternatively crypto library of the caller's choice
+ * may be used instead.
+ */
+#include "apr.h"
+#include "apr_pools.h"
+#include "apu_errno.h"
+#include "apr_strings.h"
+#include "apr_buckets.h"
+#include "apr_json.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @package Apache JOSE library
+ *
+ */
+
+/**
+ * HMAC using SHA-256
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_HS256 "HS256"
+
+/**
+ * HMAC using SHA-384
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_HS384 "HS384"
+
+/**
+ * HMAC using SHA-512
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_HS512 "HS512"
+
+/**
+ * RSASSA-PKCS1-v1_5 using SHA-256
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_RS256 "RS256"
+
+/**
+ * RSASSA-PKCS1-v1_5 using SHA-384
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_RS384 "RS384"
+
+/**
+ * RSASSA-PKCS1-v1_5 using SHA-512
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_RS512 "RS512"
+
+/**
+ * ECDSA using P-256 and SHA-256
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_ES256 "ES256"
+
+/**
+ * ECDSA using P-384 and SHA-384
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_ES384 "ES384"
+
+/**
+ * ECDSA using P-512 and SHA-512
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_ES512 "ES512"
+
+/**
+ * RSASSA-PSS using SHA-256 and MGF1 with SHA-256
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_PS256 "PS256"
+
+/**
+ * RSASSA-PSS using SHA-384 and MGF1 with SHA-384
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_PS384 "PS384"
+
+/**
+ * RSASSA-PSS using SHA-512 and MGF1 with SHA-512
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_PS512 "PS512"
+
+/**
+ * No digital signature or MAC performed
+ *
+ * https://tools.ietf.org/html/rfc7518#section-3.1
+ */
+#define APR_JOSE_JWA_NONE "none"
+
+/**
+ * "kty" (Key Type) Parameter
+ *
+ * https://tools.ietf.org/html/rfc7517#section-4.1
+ */
+#define APR_JOSE_JWK_KEY_TYPE "kty"
+
+/**
+ * "use" (Public Key Use) Parameter
+ *
+ * https://tools.ietf.org/html/rfc7517#section-4.2
+ */
+#define APR_JOSE_JWK_PUBLIC_KEY_USE "use"
+
+/**
+ * "key_ops" (Key Operations) Parameter
+ *
+ * https://tools.ietf.org/html/rfc7517#section-4.3
+ */
+#define APR_JOSE_JWK_KEY_OPERATIONS "key_ops"
+
+/**
+ * "keys" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7517#section-5.1
+ */
+#define APR_JOSE_JWK_KEYS "keys"
+
+/**
+ * "alg" (Algorithm) Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.1
+ * https://tools.ietf.org/html/rfc7516#section-4.1.1
+ * https://tools.ietf.org/html/rfc7517#section-4.4
+ */
+#define APR_JOSE_JWKSE_ALGORITHM "alg"
+
+/**
+ * "enc" (Encryption Algorithm) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-4.1.2
+ */
+#define APR_JOSE_JWE_ENCRYPTION "enc"
+
+/**
+ * "zip" (Compression Algorithm) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-4.1.3
+ */
+#define APR_JOSE_JWE_COMPRESSION "zip"
+
+/**
+ * "jku" (JWK Set URL) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.2
+ * https://tools.ietf.org/html/rfc7516#section-4.1.4
+ */
+#define APR_JOSE_JWSE_JWK_SET_URL "jku"
+
+/**
+ * "jwk" (JSON Web Key) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.3
+ * https://tools.ietf.org/html/rfc7516#section-4.1.5
+ */
+#define APR_JOSE_JWSE_JWK "jwk"
+
+/**
+ * "kid" (Key ID) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.4
+ * https://tools.ietf.org/html/rfc7516#section-4.1.6
+ */
+#define APR_JOSE_JWKSE_KEYID "kid"
+
+/**
+ * "x5u" (X.509 URL) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.5
+ * https://tools.ietf.org/html/rfc7516#section-4.1.7
+ */
+#define APR_JOSE_JWKSE_X509_URL "x5u"
+
+/**
+ * "x5c" (X.509 Certificate Chain) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.6
+ * https://tools.ietf.org/html/rfc7516#section-4.1.8
+ */
+#define APR_JOSE_JWKSE_X509_CHAIN "x5c"
+
+/**
+ * "x5t" (X.509 Certificate SHA-1 Thumbprint) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.7
+ * https://tools.ietf.org/html/rfc7516#section-4.1.9
+ */
+#define APR_JOSE_JWKSE_X509_SHA1_THUMBPRINT "x5t"
+
+/**
+ *"x5t#S256" (X.509 Certificate SHA-256 Thumbprint) Header
+ * Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.8
+ * https://tools.ietf.org/html/rfc7516#section-4.1.10
+ */
+#define APR_JOSE_JWKSE_X509_SHA256_THUMBPRINT "x5t#S256"
+
+/**
+ * "typ" (Type) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.9
+ * https://tools.ietf.org/html/rfc7516#section-4.1.11
+ */
+#define APR_JOSE_JWSE_TYPE "typ"
+
+/**
+ * "cty" (Content Type) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.10
+ * https://tools.ietf.org/html/rfc7516#section-4.1.12
+ */
+#define APR_JOSE_JWSE_CONTENT_TYPE "cty"
+
+/**
+ * "crit" (Critical) Header Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-4.1.11
+ * https://tools.ietf.org/html/rfc7516#section-4.1.13
+ */
+#define APR_JOSE_JWSE_CRITICAL "crit"
+
+/**
+ * "payload" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-7.2.1
+ */
+#define APR_JOSE_JWS_PAYLOAD "payload"
+
+/**
+ * "signatures" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-7.2.1
+ */
+#define APR_JOSE_JWS_SIGNATURES "signatures"
+
+/**
+ * "protected" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-7.2.1
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWSE_PROTECTED "protected"
+
+/**
+ * "header" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-7.2.1
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWSE_HEADER "header"
+
+/**
+ * "signature" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7515#section-7.2.1
+ */
+#define APR_JOSE_JWS_SIGNATURE "signature"
+
+/**
+ * "unprotected" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_UNPROTECTED "unprotected"
+
+/**
+ * "ciphertext" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_CIPHERTEXT "ciphertext"
+
+/**
+ * "recipients" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_RECIPIENTS "recipients"
+
+/**
+ * "encrypted_key" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_EKEY "encrypted_key"
+
+/**
+ * "iv" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_IV "iv"
+
+/**
+ * "tag" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_TAG "tag"
+
+/**
+ * "aad" Parameter
+ *
+ * https://tools.ietf.org/html/rfc7516#section-7.2.1
+ */
+#define APR_JOSE_JWE_AAD "aad"
+
+/**
+ * "iss" (Issuer) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.1
+ */
+#define APR_JOSE_JWT_ISSUER "iss"
+
+/**
+ * "sub" (Subject) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.2
+ */
+#define APR_JOSE_JWT_SUBJECT "sub"
+
+/**
+ * "aud" (Audience) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.3
+ */
+#define APR_JOSE_JWT_AUDIENCE "aud"
+
+/**
+ * "exp" (Expiration Time) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.4
+ */
+#define APR_JOSE_JWT_EXPIRATION_TIME "exp"
+
+/**
+ * "nbf" (Not Before) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.5
+ */
+#define APR_JOSE_JWT_NOT_BEFORE "nbf"
+
+/**
+ * "iat" (Issued At) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.6
+ */
+#define APR_JOSE_JWT_ISSUED_AT "iat"
+
+/**
+ * "jti" (JWT ID) Claim
+ *
+ * https://tools.ietf.org/html/rfc7519#section-4.1.7
+ */
+#define APR_JOSE_JWT_ID "jti"
+
+/**
+ * "typ" (Type) Header Parameter representing a JWT
+ *
+ * https://tools.ietf.org/html/rfc7519#section-5.1
+ */
+#define APR_JOSE_JWSE_TYPE_JWT "JWT"
+
+/**
+ * Default options.
+ */
+#define APR_JOSE_FLAG_NONE 0
+
+/**
+ * Return the full JOSE structure, instead of innermost nested structure.
+ */
+#define APR_JOSE_FLAG_DECODE_ALL 1
+
+/**
+ * When verifying or decrypting, break out of processing.
+ *
+ * If the verification or decryption failed, processing will be aborted
+ * with the given error.
+ *
+ * If the verification or decryption succeeded, processing will be considered
+ * successful and will move on to the nested structure.
+ */
+#define APR_JOSE_FLAG_BREAK 2
+
+/**
+ * Forward declaration of the apr_jose_t structure.
+ */
+typedef struct apr_jose_t apr_jose_t;
+
+/**
+ * Enum that represents the type of JOSE object.
+ */
+typedef enum apr_jose_type_e {
+ /** No specific type. */
+ APR_JOSE_TYPE_NONE = 0,
+ /** JSON Web Key (JWK) */
+ APR_JOSE_TYPE_JWK = 1,
+ /** JSON Web Key Set (JWKS) */
+ APR_JOSE_TYPE_JWKS,
+ /** JSON Web Signature (JWS) - compact encoding */
+ APR_JOSE_TYPE_JWS,
+ /** JSON Web Signature (JWS) - JSON encoding */
+ APR_JOSE_TYPE_JWS_JSON,
+ /** JSON Web Encryption (JWE) - compact encoding */
+ APR_JOSE_TYPE_JWE,
+ /** JSON Web Encryption (JWE) - JSON encoding */
+ APR_JOSE_TYPE_JWE_JSON,
+ /** JSON Web Token (JWT) */
+ APR_JOSE_TYPE_JWT,
+ /** Generic binary data */
+ APR_JOSE_TYPE_DATA,
+ /** Generic text data */
+ APR_JOSE_TYPE_TEXT,
+ /** Generic JSON structure */
+ APR_JOSE_TYPE_JSON
+} apr_jose_type_e;
+
+/**
+ * Unsigned char data of a given length
+ */
+typedef struct apr_jose_data_t {
+ /** Pointer to the data */
+ const unsigned char *data;
+ /** Length of the data */
+ apr_size_t len;
+} apr_jose_data_t;
+
+/**
+ * Signed char data of a given length
+ */
+typedef struct apr_jose_text_t {
+ /** Pointer to the text */
+ const char *text;
+ /** Length of the text */
+ apr_size_t len;
+} apr_jose_text_t;
+
+/**
+ * JSON object
+ */
+typedef struct apr_jose_json_t {
+ /** Parsed JSON structure. */
+ apr_json_value_t *json;
+} apr_jose_json_t;
+
+/**
+ * A JSON web key
+ */
+typedef struct apr_jose_jwk_t {
+ /** Parsed JWK JSON structure */
+ apr_json_value_t *key;
+} apr_jose_jwk_t;
+
+/**
+ * A JSON web key set
+ */
+typedef struct apr_jose_jwks_t {
+ /** Parsed JWK set JSON structure containing a JSON array */
+ apr_json_value_t *keys;
+} apr_jose_jwks_t;
+
+/**
+ * A single signature within a a JSON web signature.
+ */
+typedef struct apr_jose_signature_t {
+ /** JWS Header */
+ apr_json_value_t *header;
+ /** JWS Protected Header */
+ apr_json_value_t *protected_header;
+ /** JWS Signature */
+ apr_jose_data_t sig;
+ /** Result of verification for this signature */
+ apr_status_t status;
+} apr_jose_signature_t;
+
+/**
+ * A JSON web signature
+ */
+typedef struct apr_jose_jws_t {
+ /** JWS Compact / Flattened Signature */
+ apr_jose_signature_t *signature;
+ /** JWS General Signatures */
+ apr_array_header_t *signatures;
+ /** JWS Payload */
+ apr_jose_t *payload;
+} apr_jose_jws_t;
+
+/**
+ * An encrypted payload within a a JSON web encryption.
+ */
+typedef struct apr_jose_encryption_t {
+ /** JWE Shared Header */
+ apr_json_value_t *unprotected;
+ /** JWE Protected Header */
+ apr_json_value_t *protected;
+ /** JWE Protected Header (basde64url) */
+ apr_jose_text_t protected64;
+ /** JWE Initialization Vector */
+ apr_jose_data_t iv;
+ /** JWE AAD */
+ apr_jose_data_t aad;
+ /** JWE AAD (base64url)*/
+ apr_jose_text_t aad64;
+ /** JWE Ciphertext */
+ apr_jose_data_t cipher;
+ /** JWE Authentication Tag */
+ apr_jose_data_t tag;
+} apr_jose_encryption_t;
+
+/**
+ * A single recipient within a a JSON web encryption.
+ */
+typedef struct apr_jose_recipient_t {
+ /** JWE Header */
+ apr_json_value_t *header;
+ /** JWE Encrypted Key */
+ apr_jose_data_t ekey;
+ /** Result of decryption for this recipient */
+ apr_status_t status;
+} apr_jose_recipient_t;
+
+/**
+ * A JSON web encryption
+ */
+typedef struct apr_jose_jwe_t {
+ /** JWE Compact / Flattened Recipient */
+ apr_jose_recipient_t *recipient;
+ /** JWE General Recipients */
+ apr_array_header_t *recipients;
+ /** JWE Encryption Parameters */
+ apr_jose_encryption_t *encryption;
+ /** JWE Payload */
+ apr_jose_t *payload;
+} apr_jose_jwe_t;
+
+/**
+ * A JSON web token
+ */
+typedef struct apr_jose_jwt_t {
+ /** Claims associated with the JWT. */
+ apr_json_value_t *claims;
+} apr_jose_jwt_t;
+
+/**
+ * One JOSE structure to rule them all.
+ */
+struct apr_jose_t {
+ /** pool used for allocation */
+ apr_pool_t *pool;
+ /** content type of this structure */
+ const char *typ;
+ /** content type of the payload */
+ const char *cty;
+ /** result of the operation */
+ apu_err_t result;
+ /** type of the value */
+ apr_jose_type_e type;
+ /** actual value, depending on the type */
+ union {
+ apr_jose_jwk_t *jwk;
+ apr_jose_jwks_t *jwks;
+ apr_jose_jws_t *jws;
+ apr_jose_jwe_t *jwe;
+ apr_jose_jwt_t *jwt;
+ apr_jose_data_t *data;
+ apr_jose_text_t *text;
+ apr_jose_json_t *json;
+ } jose;
+};
+
+/**
+ * Callbacks for encryption, decryption, signing and verifying.
+ */
+typedef struct apr_jose_cb_t {
+ /**
+ * Callback that encrypts the content of the bucket brigade bb based
+ * on the parameters provided by the jwe->protected_header, and writes
+ * the resulting encrypted key to recipient->ekey, the initialisation vector
+ * to encryption->iv, the additional authentication data to encryption->aad, the
+ * cipher text to encryption->cipher, and the tag to encryption->tag.
+ *
+ * The encrypt function is expected to perform some or all of the
+ * following steps:
+ *
+ * 1. Determine the Key Management Mode employed by the algorithm used
+ * to determine the Content Encryption Key value. (This is the
+ * algorithm recorded in the "alg" (algorithm) Header Parameter of
+ * the resulting JWE.)
+ *
+ * 2. When Key Wrapping, Key Encryption, or Key Agreement with Key
+ * Wrapping are employed, generate a random CEK value. See RFC
+ * 4086 [RFC4086] for considerations on generating random values.
+ * The CEK MUST have a length equal to that required for the
+ * content encryption algorithm.
+ *
+ * 3. When Direct Key Agreement or Key Agreement with Key Wrapping are
+ * employed, use the key agreement algorithm to compute the value
+ * of the agreed upon key. When Direct Key Agreement is employed,
+ * let the CEK be the agreed upon key. When Key Agreement with Key
+ * Wrapping is employed, the agreed upon key will be used to wrap
+ * the CEK.
+ *
+ * 4. When Key Wrapping, Key Encryption, or Key Agreement with Key
+ * Wrapping are employed, encrypt the CEK to the recipient and let
+ * the result be the JWE Encrypted Key.
+ *
+ * 5. When Direct Key Agreement or Direct Encryption are employed, let
+ * the JWE Encrypted Key be the empty octet sequence.
+ *
+ * 6. When Direct Encryption is employed, let the CEK be the shared
+ * symmetric key.
+ *
+ * 8. If the JWE JSON Serialization is being used, repeat this process
+ * (steps 1-7) for each recipient.
+ *
+ * 9. Generate a random JWE Initialization Vector of the correct size
+ * for the content encryption algorithm (if required for the
+ * algorithm); otherwise, let the JWE Initialization Vector be the
+ * empty octet sequence.
+ *
+ * 11. If a "zip" parameter was included, compress the plaintext using
+ * the specified compression algorithm and let M be the octet
+ * sequence representing the compressed plaintext; otherwise, let M
+ * be the octet sequence representing the plaintext.
+ *
+ * 12. Create the JSON object(s) containing the desired set of Header
+ * Parameters, which together comprise the JOSE Header: one or more
+ * of the JWE Protected Header, the JWE Shared Unprotected Header,
+ * and the JWE Per-Recipient Unprotected Header.
+ *
+ * 13. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE
+ * Protected Header)). If the JWE Protected Header is not present
+ * (which can only happen when using the JWE JSON Serialization and
+ * no "protected" member is present), let this value be the empty
+ * string.
+ *
+ * 14. Let the Additional Authenticated Data encryption parameter be
+ * ASCII(Encoded Protected Header). However, if a JWE AAD value is
+ * present (which can only be the case when using the JWE JSON
+ * Serialization), instead let the Additional Authenticated Data
+ * encryption parameter be ASCII(Encoded Protected Header || '.' ||
+ * BASE64URL(JWE AAD)).
+ *
+ * 15. Encrypt M using the CEK, the JWE Initialization Vector, and the
+ * Additional Authenticated Data value using the specified content
+ * encryption algorithm to create the JWE Ciphertext value and the
+ * JWE Authentication Tag (which is the Authentication Tag output
+ * from the encryption operation).
+ *
+ * @param bb Brigade containing data to be encrypted.
+ * @param jose The JOSE structure.
+ * @param recipient Structure containing details of the recipient of
+ * this message.
+ * @param encryption Structure to be filled out by the callback
+ * containing the encrypted message.
+ * @param ctx A context.
+ * @param pool The pool to use.
+ * @return APR_SUCCESS if encrypted successfully, APR_ENOTIMPL if
+ * encryption is not supported, or any other suitable error. The
+ * jose->result structure may be filled out with further details of
+ * any error.
+ */
+ apr_status_t (*encrypt)(apr_bucket_brigade *bb, apr_jose_t *jose,
+ apr_jose_recipient_t *recipient, apr_jose_encryption_t *encryption,
+ void *ctx, apr_pool_t *pool);
+ /**
+ * Callback that decrypts the ciphertext based
+ * on the parameters provided by the recipient and encryption parameters, and writes
+ * the resulting decrypted value to the bucket brigade. Base64url versions of the
+ * protected header and the aad are provided as part of the JWE decryption
+ * mechanism.
+ *
+ * For security reasons, this callback MUST verify that the algorithm
+ * present in the JWE matches the algorithm expected by the decoder.
+ *
+ * The decrypt function is expected to perform some or all of the
+ * following steps:
+ *
+ * 6. Determine the Key Management Mode employed by the algorithm
+ * specified by the "alg" (algorithm) Header Parameter.
+ *
+ * 7. Verify that the JWE uses a key known to the recipient.
+ *
+ * 8. When Direct Key Agreement or Key Agreement with Key Wrapping are
+ * employed, use the key agreement algorithm to compute the value
+ * of the agreed upon key. When Direct Key Agreement is employed,
+ * let the CEK be the agreed upon key. When Key Agreement with Key
+ * Wrapping is employed, the agreed upon key will be used to
+ * decrypt the JWE Encrypted Key.
+ *
+ * 9. When Key Wrapping, Key Encryption, or Key Agreement with Key
+ * Wrapping are employed, decrypt the JWE Encrypted Key to produce
+ * the CEK. The CEK MUST have a length equal to that required for
+ * the content encryption algorithm. Note that when there are
+ * multiple recipients, each recipient will only be able to decrypt
+ * JWE Encrypted Key values that were encrypted to a key in that
+ * recipient's possession. It is therefore normal to only be able
+ * to decrypt one of the per-recipient JWE Encrypted Key values to
+ * obtain the CEK value. Also, see Section 11.5 for security
+ * considerations on mitigating timing attacks.
+ *
+ * 10. When Direct Key Agreement or Direct Encryption are employed,
+ * verify that the JWE Encrypted Key value is an empty octet
+ * sequence.
+ *
+ * 11. When Direct Encryption is employed, let the CEK be the shared
+ * symmetric key.
+ *
+ * 12. Record whether the CEK could be successfully determined for this
+ * recipient or not.
+ *
+ * 13. If the JWE JSON Serialization is being used, repeat this process
+ * (steps 4-12) for each recipient contained in the representation.
+ *
+ * 14. Compute the Encoded Protected Header value BASE64URL(UTF8(JWE
+ * Protected Header)). If the JWE Protected Header is not present
+ * (which can only happen when using the JWE JSON Serialization and
+ * no "protected" member is present), let this value be the empty
+ * string.
+ *
+ * 15. Let the Additional Authenticated Data encryption parameter be
+ * ASCII(Encoded Protected Header). However, if a JWE AAD value is
+ * present (which can only be the case when using the JWE JSON
+ * Serialization), instead let the Additional Authenticated Data
+ * encryption parameter be ASCII(Encoded Protected Header || '.' ||
+ * BASE64URL(JWE AAD)).
+ *
+ * 16. Decrypt the JWE Ciphertext using the CEK, the JWE Initialization
+ * Vector, the Additional Authenticated Data value, and the JWE
+ * Authentication Tag (which is the Authentication Tag input to the
+ * calculation) using the specified content encryption algorithm,
+ * returning the decrypted plaintext and validating the JWE
+ * Authentication Tag in the manner specified for the algorithm,
+ * rejecting the input without emitting any decrypted output if the
+ * JWE Authentication Tag is incorrect.
+ *
+ * 17. If a "zip" parameter was included, uncompress the decrypted
+ * plaintext using the specified compression algorithm.
+ *
+ * @param bb Brigade where decrypted data is to be written.
+ * @param jose The JOSE structure.
+ * @param recipient Structure containing details of the recipient of
+ * this message, to be used to decrypt the message.
+ * @param encryption Structure containing the encrypted message.
+ * @param header The JOSE protected header.
+ * @param p64 The JOSE protected header in original BASE64URL format,
+ * for use during decryption.
+ * @param aad64 The JOSE additional authenticated data in original
+ * BASE64URL format, for use during decryption.
+ * @param ctx A context.
+ * @param dflags A pointer to a flag. Set to APR_JOSE_FLAG_NONE for
+ * decryption to continue to the next recipient in the JWE, or
+ * APR_JOSE_FLAG_BREAK to stop decrypting further recipients.
+ * @param pool The pool to use.
+ * @return APR_SUCCESS if decrypted successfully, APR_ENOTIMPL if
+ * decryption is not supported, or any other suitable error. The
+ * jose->result structure may be filled out with further details of
+ * any error.
+ */
+ apr_status_t (*decrypt)(apr_bucket_brigade *bb, apr_jose_t *jose,
+ apr_jose_recipient_t *recipient, apr_jose_encryption_t *encryption,
+ apr_json_value_t *header, apr_jose_text_t *ph64,
+ apr_jose_text_t *aad64, void *ctx, int *dflags, apr_pool_t *pool);
+ /**
+ * Callback that signs the content of the bucket brigade bb based
+ * on the parameters provided by the signature protected header, and writes
+ * the resulting binary signature to signature->sig.
+ *
+ * The sign function is expected to perform some or all of the
+ * following steps:
+ *
+ * 5. Compute the JWS Signature in the manner defined for the
+ * particular algorithm being used over the JWS Signing Input
+ * ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' ||
+ * BASE64URL(JWS Payload)). The "alg" (algorithm) Header Parameter
+ * MUST be present in the JOSE Header, with the algorithm value
+ * accurately representing the algorithm used to construct the JWS
+ * Signature.
+ *
+ * @param bb Brigade containing data to be signed.
+ * @param jose The JOSE structure.
+ * @param signature Structure to be filled out by the callback
+ * containing the signature of the message.
+ * @param ctx A context.
+ * @param pool The pool to use.
+ * @return APR_SUCCESS if signed successfully, APR_ENOTIMPL if
+ * signing is not supported, or any other suitable error. The
+ * jose->result structure may be filled out with further details of
+ * any error.
+ */
+ apr_status_t (*sign)(apr_bucket_brigade *bb, apr_jose_t *jose,
+ apr_jose_signature_t *signature, void *ctx, apr_pool_t *pool);
+ /**
+ * Callback that verifies the content of the bucket brigade bb based
+ * on the parameters provided by the signature protected header and
+ * signature->sig.
+ *
+ * For security reasons, this callback MUST verify that the algorithm
+ * present in the JWS matches the algorithm expected by the decoder.
+ *
+ * The verify function is expected to perform some or all of the
+ * following steps:
+ *
+ * 8. Validate the JWS Signature against the JWS Signing Input
+ * ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' ||
+ * BASE64URL(JWS Payload)) in the manner defined for the algorithm
+ * being used, which MUST be accurately represented by the value of
+ * the "alg" (algorithm) Header Parameter, which MUST be present.
+ * See Section 10.6 for security considerations on algorithm
+ * validation. Record whether the validation succeeded or not.
+ *
+ * 9. If the JWS JSON Serialization is being used, repeat this process
+ * (steps 4-8) for each digital signature or MAC value contained in
+ * the representation.
+ *
+ * 10. If none of the validations in step 9 succeeded, then the JWS MUST
+ * be considered invalid. Otherwise, in the JWS JSON Serialization
+ * case, return a result to the application indicating which of the
+ * validations succeeded and failed. In the JWS Compact
+ * Serialization case, the result can simply indicate whether or not
+ * the JWS was successfully validated.
+ *
+ * @param bb Brigade containing data to be verified.
+ * @param jose The JOSE structure.
+ * @param signature Structure containing the signature to be verified.
+ * @param ctx A context.
+ * @param dflags A pointer to a flag. Set to APR_JOSE_FLAG_NONE for
+ * verification to continue to the next recipient in the JWE, or
+ * APR_JOSE_FLAG_BREAK to stop verifying further recipients.
+ * @param pool The pool to use.
+ * @return APR_SUCCESS if verified successfully, APR_ENOTIMPL if
+ * verification is not supported, or any other suitable error. The
+ * jose->result structure may be filled out with further details of
+ * any error.
+ */
+ apr_status_t (*verify)(apr_bucket_brigade *bb, apr_jose_t *jose,
+ apr_jose_signature_t *signature, void *ctx, int *vflags,
+ apr_pool_t *pool);
+ /** Context to be passed to the callback. */
+ void *ctx;
+} apr_jose_cb_t;
+
+/**
+ * @brief Get the result of the last operation on the jose. If the result
+ * is NULL, the operation was successful.
+ * @param jose - context pointer
+ * @return The apu_err_t is returned.
+ */
+APR_DECLARE(apu_err_t *) apr_jose_error(apr_jose_t *jose);
+
+/**
+ * Make a generic JOSE structure.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param type the type of structure to create.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_make(apr_jose_t **jose, apr_jose_type_e type,
+ apr_pool_t *pool);
+
+/**
+ * Make a JSON Web Key for encoding or decoding.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param key the json representing the key. May be NULL.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jwk_make(apr_jose_t **jose,
+ apr_json_value_t *key, apr_pool_t *pool);
+
+/**
+ * Make a JSON Web Key Set.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param keys the array of keys in JSON format. May be NULL.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jwks_make(apr_jose_t **jose,
+ apr_json_value_t *keys, apr_pool_t *pool);
+
+/**
+ * Make a signature structure for JWS.
+ *
+ * @param signature the result.
+ * @param header the unprotected header.
+ * @param protected the protected header.
+ * @param pool the pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_jose_signature_make(
+ apr_jose_signature_t **signature, apr_json_value_t *header,
+ apr_json_value_t *protected, apr_pool_t *pool);
+
+/**
+ * Make a recipient structure for JWE.
+ *
+ * @param recipient the result.
+ * @param unprotected the unprotected header.
+ * @param pool the pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_jose_recipient_make(apr_jose_recipient_t **recipient,
+ apr_json_value_t *unprotected, apr_pool_t *pool);
+
+/**
+ * Make an encryption structure for JWE.
+ *
+ * @param encryption the result.
+ * @param unprotected the unprotected shared header.
+ * @param protected the protected header.
+ * @param pool the pool to use.
+ */
+APR_DECLARE(apr_status_t) apr_jose_encryption_make(apr_jose_encryption_t **encryption,
+ apr_json_value_t *unprotected, apr_json_value_t *protected,
+ apr_pool_t *pool);
+
+/**
+ * Make a compact encoded JWE.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param recipient the recipient for compact / flattened JWE.
+ * @param recipients the recipients array for general JWE.
+ * @param encryption the encryption structure.
+ * @param payload the JOSE payload to encrypt.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jwe_make(apr_jose_t **jose,
+ apr_jose_recipient_t *recipient, apr_array_header_t *recipients,
+ apr_jose_encryption_t *encryption, apr_jose_t *payload,
+ apr_pool_t *pool);
+
+/**
+ * Make a JSON encoded JWE.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param recipient the recipient for compact / flattened JWE.
+ * @param recipients the recipients array for general JWE.
+ * @param encryption the encryption structure.
+ * @param payload the JOSE payload to encrypt.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jwe_json_make(apr_jose_t **jose,
+ apr_jose_recipient_t *recipient,
+ apr_array_header_t *recipients, apr_jose_encryption_t *encryption,
+ apr_jose_t *payload, apr_pool_t *pool);
+
+/**
+ * Make a compact encoded JWS.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param signature the header / protected header / signature used with compact or flattened syntax. May be NULL.
+ * @param signatures array of header / protected header / signature used with general JSON syntax.
+ * @param payload the payload to be wrapped by this JWS.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jws_make(apr_jose_t **jose,
+ apr_jose_signature_t *signature, apr_array_header_t *signatures,
+ apr_jose_t *payload, apr_pool_t *pool);
+
+/**
+ * Make a JSON encoded JWS.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param signature the header / protected header / signature used with compact or flattened syntax. May be NULL.
+ * @param signatures array of header / protected header / signature used with general JSON syntax.
+ * @param payload the payload to be wrapped by this JWS.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jws_json_make(apr_jose_t **jose,
+ apr_jose_signature_t *signature, apr_array_header_t *signatures,
+ apr_jose_t *payload, apr_pool_t *pool);
+
+/**
+ * Make a JWT claims payload.
+ *
+ * To create a useful JWT, this payload needs to be wrapped in a JWS
+ * or JWE (or both), as required by the caller.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param claims the claims to sign.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_jwt_make(apr_jose_t **jose,
+ apr_json_value_t *claims, apr_pool_t *pool);
+
+/**
+ * Make a data buffer for encoding from the given data and length.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param typ the content type of this data.
+ * @param in the plaintext to sign.
+ * @param inlen length of the plaintext.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_data_make(apr_jose_t **jose, const char *typ,
+ const unsigned char *in, apr_size_t inlen, apr_pool_t *pool);
+
+/**
+ * Make a UTF-8 text buffer for encoding from the given string
+ * and length.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param cty the content type.
+ * @param in the UTF-8 encoded text string.
+ * @param inlen length of the UTF-8 encoded text string.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_text_make(apr_jose_t **jose, const char *cty,
+ const char *in, apr_size_t inlen, apr_pool_t *pool);
+
+/**
+ * Make a json structure for encoding.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param cty the content type.
+ * @param json the json object to add.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_json_make(apr_jose_t **jose, const char *cty,
+ apr_json_value_t *json, apr_pool_t *pool);
+
+/**
+ * Sign or encrypt the apr_jose_t, and write it to the brigade.
+ * @param brigade brigade the result will be appended to.
+ * @param flush The flush function to use if the brigade is full
+ * @param ctx The structure to pass to the flush function
+ * @param jose the JOSE to encode.
+ * @param cb callbacks for sign and encrypt.
+ * @param pool pool to be used.
+ * @return APR_SUCCESS is returned if encoding was successful, otherwise
+ * an APR status code, along with an apu_err_t with an explanation
+ * allocated from jose->pool.
+ */
+APR_DECLARE(apr_status_t) apr_jose_encode(apr_bucket_brigade *brigade,
+ apr_brigade_flush flush, void *ctx, apr_jose_t *jose,
+ apr_jose_cb_t *cb, apr_pool_t *pool);
+
+/**
+ * Decode, decrypt and verify the utf8-encoded JOSE string into apr_jose_t.
+ *
+ * The JOSE structure may be nested to the given limit.
+ * @param jose If jose points at NULL, a JOSE structure will be
+ * created. If the jose pointer is not NULL, the structure will
+ * be reused.
+ * @param typ content type of this object.
+ * @param brigade the JOSE structure to decode.
+ * @param cb callbacks for verify and decrypt.
+ * @param level depth limit of JOSE and JSON nesting.
+ * @param flags APR_JOSE_FLAG_NONE to return payload only. APR_JOSE_FLAG_DECODE_ALL
+ * to return the full JWS/JWE structure.
+ * @param pool pool used to allocate the result from.
+ */
+APR_DECLARE(apr_status_t) apr_jose_decode(apr_jose_t **jose, const char *typ,
+ apr_bucket_brigade *brigade, apr_jose_cb_t *cb, int level, int flags,
+ apr_pool_t *pool);
+
+
+#ifdef __cplusplus
+}
+#endif
+/** @} */
+#endif /* APR_JOSE_H */
Propchange: apr/apr/trunk/include/apr_jose.h
------------------------------------------------------------------------------
svn:eol-style = native