pax_global_header00006660000000000000000000000064145247211710014516gustar00rootroot0000000000000052 comment=89d77410ada438212c8c5b800a82cb04349f1382 rhonabwy-1.1.13/000077500000000000000000000000001452472117100134325ustar00rootroot00000000000000rhonabwy-1.1.13/.github/000077500000000000000000000000001452472117100147725ustar00rootroot00000000000000rhonabwy-1.1.13/.github/workflows/000077500000000000000000000000001452472117100170275ustar00rootroot00000000000000rhonabwy-1.1.13/.github/workflows/ccpp.yml000066400000000000000000000036151452472117100205040ustar00rootroot00000000000000name: C/C++ CI on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: install dependencies run: | sudo apt-get update sudo apt-get install -y cmake pkg-config check libsubunit-dev cppcheck libsystemd-dev libgnutls28-dev libjansson-dev libcurl4-gnutls-dev libmicrohttpd-dev valgrind doxygen gnutls-bin - name: cppcheck run: cppcheck --force --enable=warning,missingInclude --error-exitcode=1 . - name: dependencies run: | cd /opt git clone https://github.com/babelouest/orcania.git git clone https://github.com/babelouest/yder.git git clone https://github.com/babelouest/ulfius.git mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../orcania make sudo make install rm -rf * cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../yder make sudo make install rm -rf * cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../ulfius make sudo make install rm -rf * - name: build run: | # prepare build folders mkdir build # build rhonabwy, run tests, build package cd build cmake -DBUILD_RHONABWY_TESTING=ON -DBUILD_RHONABWY_DOCUMENTATION=ON -DWITH_CURL=OFF .. make rm -rf * cmake -DBUILD_RHONABWY_TESTING=ON -DBUILD_RHONABWY_DOCUMENTATION=ON .. ../test/cert/create-cert.sh || (cat ../test/cert/certtool.log && false) ln -s ../test/cert/ . ln -s ../test/cookbook-master . ln -s ../test/ . make test || (cat Testing/Temporary/LastTest.log && false) make package make doc sudo make install sudo ldconfig # test rnbyc cd ../tools/rnbyc/ make test rhonabwy-1.1.13/.github/workflows/codeql-analysis.yml000066400000000000000000000036401452472117100226450ustar00rootroot00000000000000name: "CodeQL" on: push: branches: [master, ] pull_request: # The branches below must be a subset of the branches above branches: [master] schedule: - cron: '0 21 * * 3' jobs: analyse: name: Analyse runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. fetch-depth: 2 # If this run was triggered by a pull request event, then checkout # the head of the pull request instead of the merge commit. - run: git checkout HEAD^2 if: ${{ github.event_name == 'pull_request' }} # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v2 - name: dependencies run: | sudo apt-get update sudo apt-get install -y cmake pkg-config libsystemd-dev libgnutls28-dev libjansson-dev libcurl4-gnutls-dev libmicrohttpd-dev doxygen cd /opt git clone https://github.com/babelouest/orcania.git git clone https://github.com/babelouest/yder.git git clone https://github.com/babelouest/ulfius.git mkdir build cd build cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../orcania make sudo make install rm -rf * cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../yder make sudo make install rm -rf * cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib ../ulfius make sudo make install rm -rf * - run: | mkdir build cd build cmake -DBUILD_RHONABWY_DOCUMENTATION=on .. make make doc sudo make install - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 rhonabwy-1.1.13/.gitignore000066400000000000000000000001271452472117100154220ustar00rootroot00000000000000*.o *.so *.so.* *.pc valgrind*.txt *.log rhonabwy-cfg.h tools/rnbyc/rnbyc *.jwks *.jwt rhonabwy-1.1.13/API.md000066400000000000000000001712571452472117100144020ustar00rootroot00000000000000# Rhonabwy API documentation Rhonabwy library is made to manage JWK, JWKS, JWS, JWE and JWT according to their respective RFCs: - [JSON Web Keys](https://tools.ietf.org/html/rfc7517) (JWK) and JSON Web Keys Set (JWKS) - [JSON Web Signatures](https://tools.ietf.org/html/rfc7515) (JWS) - [JSON Web Encryption](https://tools.ietf.org/html/rfc7516) (JWE) - [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) Rhonabwy is based on the following libraries and actively uses them: - GnuTLS for the cryptographic functions - Jansson for the JSON manipulation - Yder for the logs - Libcurl when it requires to retrieve keys from an URL When relevant, a function can accept or return GnuTLS or Jansson data. But if you're not using those in your application and prefer raw data, you can use the more agnostic functions. ## Return values Lots of functions in Rhonabwy library return an int value. The returned value can be one of the following: ```C #define RHN_OK 0 #define RHN_ERROR 1 #define RHN_ERROR_MEMORY 2 #define RHN_ERROR_PARAM 3 #define RHN_ERROR_UNSUPPORTED 4 #define RHN_ERROR_INVALID 5 ``` If a function is successful, it will return `RHN_OK` (0), otherwise an error code is returned. ## Global init and close It's **recommended** to use `r_global_init` and `r_global_close` at the beginning and at the end of your program to initialize and cleanup internal values and settings. This will make outgoing requests faster, especially if you use lots of them, and dispatch your memory allocation functions in curl and Jansson if you changed them. These functions are **NOT** thread-safe, so you must use them in a single thread context. ```C int r_global_init(void); void r_global_close(void); ``` ## Log messages Usually, a log message is displayed to explain more specifically what happened on error. The log manager used is [Yder](https://github.com/babelouest/yder). You can enable Yder log messages on the console with the following command at the beginning of your program: ```C int main(void) { y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy client program"); // Do your code here y_close_logs(); } ``` Example of an error log message: ``` 2020-04-05T16:14:31 - Rhonabwy: r_jwk_is_valid - Invalid alg ``` Go to Yder [API Documentation](https://babelouest.github.io/yder/) for more details. ## Memory management All typedefs managed by Rhonabwy use dedicated init and free functions. You must always use those functions to allocate or free resources manipulated by the library. ```C int r_jwk_init(jwk_t ** jwk); void r_jwk_free(jwk_t * jwk); int r_jwks_init(jwks_t ** jwks); void r_jwks_free(jwks_t * jwks); int r_jws_init(jws_t ** jws); void r_jws_free(jws_t * jws); int r_jwe_init(jwe_t ** jwe); void r_jwe_free(jwe_t * jwe); int r_jwt_init(jwt_t ** jwt); void r_jwt_free(jwt_t * jwt); ``` In addition, when a function return a `char *` value, this value must be freed using the function `r_free(void *)`. ```C void r_free(void * data); ``` And finally, all `json_t *` returned values must be de allocated using `json_decref(json_t *)`, see [Jansson Documentation](https://jansson.readthedocs.io/) for more details. ## Library information The functions `r_library_info_json_t()` and `r_library_info_json_str()` return a JSON object that represents the signature and encryption algorithms supported, as well as the library version. Example output: ```JSON { "version": "0.9.9999", "jws": { "alg": [ "none", "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "EdDSA", "PS256", "PS384", "PS512" ] }, "jwe": { "alg": [ "RSA1_5", "RSA-OAEP", "RSA-OAEP-256", "A128KW", "A192KW", "A256KW", "dir", "A128GCMKW", "A192GCMKW", "A256GCMKW", "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW", "ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW" ], "enc": [ "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A256GCM", "A192GCM" ] } } ``` ## Header or Claim integer value When using `r_jws_set_header_int_value`, `r_jwe_set_header_int_value`, `r_jwt_set_header_int_value` or `r_jwt_set_claim_int_value`, the int value must be of type `rhn_int_t`, which inner format depend on the architecture. It's recommended not to use an `int` instead, or undefined behaviour may happen. Likewise, the functions `r_jws_get_header_int_value`, `r_jwe_get_header_int_value`, `r_jwt_get_header_int_value` or `r_jwt_get_claim_int_value`, these functions will return a `rhn_int_t`. To use a `rhn_int_t` in a printf-like function, you can use the macro `RHONABWY_INTEGER_FORMAT`: ```C rhn_int_t val = 42; printf("value: %"RHONABWY_INTEGER_FORMAT"\n", val); ``` ## JWK A JWK (JSON Web Key) is a format used to store and represent a cryptographic key in a JSON object. Example of JWK: ```JSON { "kty":"EC", "crv":"P-256", "x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", "y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0", "kid":"Public key used in JWS spec Appendix A.3 example" } ``` The standard allows to store public and private keys for RSA and ECC algorithms, it also allows to store symmetric keys. In a JWK, every raw value is encoded in Base64Url format to fit in the JSON object without any issue. A JWK is represented in Rhonabwy library using the type `jwk_t *`. ### Import and Export JWK Rhonabwy allows to import and export a JWK in the following formats: - A JSON structure in a `const char *` - A JSON structure in a `json_t *` - A key or certificate in `PEM` or `DER` format - A `GnuTLS` structure of the following: `gnutls_privkey_t`, `gnutls_pubkey_t` or `gnutls_x509_crt_t` (import only) If the imported JWK contains a `x5u` property, the key or certificate will be downloaded at the given address. If so, you can give an additional parameter `x5u_flag` which values can be: - `R_FLAG_IGNORE_SERVER_CERTIFICATE`: ignore if web server certificate is invalid - `R_FLAG_FOLLOW_REDIRECT`: follow redirection if necessary - `R_FLAG_IGNORE_REMOTE`: do not download remote key, but the function may return an error ```C int r_jwk_import_from_json_str(jwk_t * jwk, const char * input); int r_jwk_import_from_json_t(jwk_t * jwk, json_t * j_input); int r_jwk_import_from_pem_der(jwk_t * jwk, int type, int format, const unsigned char * input, size_t input_len); int r_jwk_import_from_gnutls_privkey(jwk_t * jwk, gnutls_privkey_t key); int r_jwk_import_from_gnutls_pubkey(jwk_t * jwk, gnutls_pubkey_t pub); int r_jwk_import_from_gnutls_x509_crt(jwk_t * jwk, gnutls_x509_crt_t crt); int r_jwk_import_from_x5u(jwk_t * jwk, int x5u_flags, const char * x5u); int r_jwk_import_from_x5c(jwk_t * jwk, const char * x5c); int r_jwk_import_from_symmetric_key(jwk_t * jwk, const unsigned char * key, size_t key_len); int r_jwk_import_from_password(jwk_t * jwk, const char * password); int r_jwk_extract_pubkey(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int x5u_flags); jwk_t * r_jwk_quick_import(rhn_import type, ...); ``` The values `R_FLAG_IGNORE_SERVER_CERTIFICATE` and `R_FLAG_FOLLOW_REDIRECT` can be merged: `R_FLAG_IGNORE_SERVER_CERTIFICATE|R_FLAG_FOLLOW_REDIRECT` ### Manipulate JWK properties You can manipulate the JWK properties directly using the dedicated functions: ```C const char * r_jwk_get_property_str(jwk_t * jwk, const char * key); const char * r_jwk_get_property_array(jwk_t * jwk, const char * key, size_t index); int r_jwk_set_property_str(jwk_t * jwk, const char * key, const char * value); int r_jwk_set_property_array(jwk_t * jwk, const char * key, size_t index, const char * value); int r_jwk_append_property_array(jwk_t * jwk, const char * key, const char * value); int r_jwk_delete_property_str(jwk_t * jwk, const char * key); int r_jwk_delete_property_array_at(jwk_t * jwk, const char * key, size_t index); ``` ### Validate the format of a JWK The function `r_jwk_is_valid` will check the validity of a JWK, i.e. check if all the required properties are present and in the correct format. Note that this function is called each time an import is made. ### Generate a random key pair You can use Rhonabwy to generate a random key pair for RSA, ECC or OKP algorithms. The `jwk_t *` parameters must be initialized first. The `type` parameter can have one of the following values: `R_KEY_TYPE_RSA` `R_KEY_TYPE_EC`, `R_KEY_TYPE_EDDSA` or `R_KEY_TYPE_ECDH`. The `bits` parameter specifies the length of the key. A RSA key must be at least 2048 bits, and the bits value allowed for an ECC key are 256, 384 or 512. If the parameter `kid` is used, the generated key kid property will have the kid specified, otherwise a `kid` will be generated to identify the key pair. ```C int r_jwk_generate_key_pair(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int type, unsigned int bits, const char * kid); ``` ## JWKS A JWKS (JSON Web Key Set) is a format used to store and represent a set cryptographic key in a JSON object. A JWKS is always a JSON object containing the property `"keys"` that will point to an array of JWK. Example of JWKS: ```JSON { "keys": [ { "kty":"EC", "crv":"P-256", "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", "use":"enc", "kid":"1" }, { "kty":"RSA", "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e":"AQAB", "alg":"RS256", "kid":"2011-04-29" } ] } ``` In Rhonabwy library, you can manipulate the JWKS inside a JWKS by iteration or get a JWK by its kid. ```C jwk_t * r_jwks_get_at(jwks_t * jwks, size_t index); jwk_t * r_jwks_get_by_kid(jwks_t * jwks, const char * kid); ``` You can also import a JWKS using a JSON object or an URL. ```C int r_jwks_import_from_json_str(jwks_t * jwks, const char * input); int r_jwks_import_from_json_t(jwks_t * jwks, json_t * j_input); int r_jwks_import_from_uri(jwks_t * jwks, const char * uri, int flags); jwks_t * r_jwks_quick_import(rhn_import, ...); ``` ## JWT Finally, a JWT (JSON Web Token) is a JSON content signed and/or encrypted and serialized in a compact format that can be easily transferred in HTTP requests. Technically, a JWT is a JWS or a JWE which payload is a stringified JSON and has the property `"type":"JWT"` in the header. A JWT can be nested, which means signed and encrypted, in which case the payload is signed as a JWS first, then the serialized signed token is used as the payload in a JWE, or the opposite. ### Set values To set the values of the JWT (header, keys, payload, etc.), you can use the dedicated functions (see the documentation), or use the function `r_jwt_set_properties` to set multiple properties at once. The option list MUST end with the option `RHN_OPT_NONE`. ```C /** * Add multiple properties to the jwt_t * * @param jwt: the jwt_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jwt_set_properties(jwt_t * jwt, ...); ``` The available `rhn_opt` and their following values for a `jwt_t` are: ```C RHN_OPT_HEADER_INT_VALUE, const char *, int RHN_OPT_HEADER_RHN_INT_VALUE, const char *, rhn_int_t RHN_OPT_HEADER_STR_VALUE, const char * const char * RHN_OPT_HEADER_JSON_T_VALUE, const char *, json_t * RHN_OPT_HEADER_FULL_JSON_T, json_t * RHN_OPT_HEADER_FULL_JSON_STR, const char * RHN_OPT_CLAIM_INT_VALUE, const char *, int RHN_OPT_CLAIM_RHN_INT_VALUE, const char *, rhn_int_t RHN_OPT_CLAIM_STR_VALUE, const char * const char * RHN_OPT_CLAIM_JSON_T_VALUE, const char *, json_t * RHN_OPT_CLAIM_FULL_JSON_T, json_t * RHN_OPT_CLAIM_FULL_JSON_STR, const char * RHN_OPT_SIG_ALG, jwa_alg RHN_OPT_ENC_ALG, jwa_alg RHN_OPT_ENC, jwa_enc RHN_OPT_CIPHER_KEY, const unsigned char *, size_t RHN_OPT_IV, const unsigned char *, size_t RHN_OPT_SIGN_KEY_JWK, jwk_t * RHN_OPT_SIGN_KEY_JWKS, jwks_t * RHN_OPT_SIGN_KEY_GNUTLS, gnutls_privkey_t RHN_OPT_SIGN_KEY_JSON_T, json_t * RHN_OPT_SIGN_KEY_JSON_STR, const char * RHN_OPT_SIGN_KEY_PEM_DER, uint, const unsigned char *, size_t RHN_OPT_VERIFY_KEY_JWK, jwk_t * RHN_OPT_VERIFY_KEY_JWKS, jwks_t * RHN_OPT_VERIFY_KEY_GNUTLS, gnutls_pubkey_t RHN_OPT_VERIFY_KEY_JSON_T, json_t * RHN_OPT_VERIFY_KEY_JSON_STR, const char * RHN_OPT_VERIFY_KEY_PEM_DER, uint, const unsigned char *, size_t RHN_OPT_ENCRYPT_KEY_JWK, jwk_t * RHN_OPT_ENCRYPT_KEY_JWKS, jwks_t * RHN_OPT_ENCRYPT_KEY_GNUTLS, gnutls_pubkey_t RHN_OPT_ENCRYPT_KEY_JSON_T, json_t * RHN_OPT_ENCRYPT_KEY_JSON_STR, const char * RHN_OPT_ENCRYPT_KEY_PEM_DER, uint, const unsigned char *, size_t RHN_OPT_DECRYPT_KEY_JWK, jwk_t * RHN_OPT_DECRYPT_KEY_JWKS, jwks_t * RHN_OPT_DECRYPT_KEY_GNUTLS, gnutls_privkey_t RHN_OPT_DECRYPT_KEY_JSON_T, json_t * RHN_OPT_DECRYPT_KEY_JSON_STR, const char * RHN_OPT_DECRYPT_KEY_PEM_DER, uint, const unsigned char *, size_t ``` Example of usage for `r_jwt_set_properties`: ```C jwt_t * jwt; jwk_t * jwk; // Set a private RSA key in this value r_jwt_set_properties(jwt, RHN_OPT_HEADER_INT_VALUE, "int", 42, RHN_OPT_HEADER_STR_VALUE, "str", "a value", RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_CLAIM_FULL_JSON_STR, "{\"str\":\"grut\",\"int\":42,\"obj\":true}", RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_SIGN_KEY_JWK, jwk, RHN_OPT_NONE); // Test if return value is RHN_OK char * token = r_jwt_serialize_signed(jwt, NULL, 0); } ``` ### Verify a list of claims in the JWT The function int `int r_jwt_validate_claims(jwt_t * jwt, ...)` will help you verify the validity of some claims in the JWT. Claim types available - `R_JWT_CLAIM_ISS`: claim `"iss"`, values expected a string or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_SUB`: claim `"sub"`, values expected a string or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_AUD`: claim `"aud"`, values expected a string or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_EXP`: claim `"exp"`, value expected `R_JWT_CLAIM_NOW` or an positive integer value or `R_JWT_CLAIM_PRESENT` to validate the presence of the claim - `R_JWT_CLAIM_NBF`: claim `"nbf"`, value expected `R_JWT_CLAIM_NOW` or an positive integer value or `R_JWT_CLAIM_PRESENT` to validate the presence of the claim - `R_JWT_CLAIM_IAT`: claim `"iat"`, value expected `R_JWT_CLAIM_NOW` or an positive integer value or `R_JWT_CLAIM_PRESENT` to validate the presence of the claim - `R_JWT_CLAIM_JTI`: claim `"jti"`, values expected a string or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_STR`: the claim name specified must have the string value expected or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_INT`: the claim name specified must have the integer value expected - `R_JWT_CLAIM_JSN`: the claim name specified must have the json_t * value expected or `NULL` to validate the presence of the claim - `R_JWT_CLAIM_TYP`: header parameter `"typ"` (type), values expected a string or `NULL` to validate the presence of the header parameter - `R_JWT_CLAIM_CTY`: header parameter `"cty"` (Content Type), values expected a string or `NULL` to validate the presence of the header parameter For example, the following code will check the jwt against the claim `iss` has the value `"https://example.com"`, the claim `sub` has the value `"client_1"`, the presence of the claim `aud`, the claim `exp` is after now, the claim `nbf` is before now, the claim `scope` has the value `"scope1"`, the claim `age` has the value `42` and the claim `verified` has the JSON value `true`: ```C if (r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, "https://example.com", R_JWT_CLAIM_SUB, "client_1", R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", "scope1", R_JWT_CLAIM_INT, "age", 42, R_JWT_CLAIM_JSN, "verified", json_true(), R_JWT_CLAIM_NOP) == RHN_OK) ``` ### Serialize a JWT using Rhonabwy Let's use the following JSON object in a JWT: ```JSON { "iss":"joe", "exp":1300819380, "http://example.com/is_root":true } ``` The JWT can be signed using the algorithm `HS256` and the following key: ```JSON { "kty":"oct", "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" } ``` The signed JWT serialized will be: ``` eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk ``` #### Signed JWT The signed JWT above can be created with the following sample code: ```C #include jwt_t * jwt = NULL; jwk_t * jwk_key = NULL; const char payload[] = "{\"iss\":\"joe\",\"exp\":1300819380,\"http://example.com/is_root\":true}", jwk_key_str[] = "{\"kty\":\"oct\",\"k\":\"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow\"}"; char * token = NULL; if (r_jwk_init(&jwk_key) == RHN_OK && r_jwt_init(&jwt) == RHN_OK && r_jwk_import_from_json_str(jwk_key, jwk_key_str) == RHN_OK && r_jwt_set_sign_alg(jwt, R_JWA_ALG_HS256) == RHN_OK && r_jwt_set_full_claims_json_str(jwt, payload) == RHN_OK) { token = r_jwt_serialize_signed(jwt, jwk_key, 0); // token will store the signed token } r_free(token); r_jwt_free(jwt); r_jwk_free(jwk_key); ``` The same payload can be encrypted and serialized in an encrypted JWT using `RSA1_5` as key encryption algorithm and `A128CBC-HS256` as content encryption algorithm. The encrypted JWT of the payload above can be the following: ``` eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.QR1Owv2ug2WyPBnbQrRARTeEk9kDO2w8qDcjiHnSJflSdv1iNqhWXaKH4MqAkQtMoNfABIPJaZm0HaA415sv3aeuBWnD8J-Ui7Ah6cWafs3ZwwFKDFUUsWHSK-IPKxLGTkND09XyjORj_CHAgOPJ-Sd8ONQRnJvWn_hXV1BNMHzUjPyYwEsRhDhzjAD26imasOTsgruobpYGoQcXUwFDn7moXPRfDE8-NoQX7N7ZYMmpUDkR-Cx9obNGwJQ3nM52YCitxoQVPzjbl7WBuB7AohdBoZOdZ24WlN1lVIeh8v1K4krB8xgKvRU8kgFrEn_a1rZgN5TiysnmzTROF869lQ.AxY8DCtDaGlsbGljb3RoZQ.MKOle7UQrG6nSxTLX6Mqwt0orbHvAKeWnDYvpIAeZ72deHxz3roJDXQyhxx0wKaMHDjUEOKIwrtkHthpqEanSBNYHZgmNOV7sln1Eu9g3J8.fiK51VwhsxJ-siBMR-YFiA ``` #### Encrypted JWT An encrypted JWT can be created with Rhonabwy using the following sample code: ```C #include jwt_t * jwt = NULL; jwk_t * jwk_key = NULL; const char payload[] = "{\"iss\":\"joe\",\"exp\":1300819380,\"http://example.com/is_root\":true}", jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; char * token = NULL; if (r_jwk_init(&jwk_key) == RHN_OK && r_jwt_init(&jwt) == RHN_OK && r_jwk_import_from_json_str(jwk_key, jwk_pubkey_rsa_str) == RHN_OK && r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5) == RHN_OK && r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC) == RHN_OK && r_jwt_set_full_claims_json_str(jwt, payload) == RHN_OK) { token = r_jwt_serialize_encrypted(jwt, jwk_key, 0); // token will store the encrypted token } r_free(token); r_jwt_free(jwt); r_jwk_free(jwk_key); ``` #### Nested JWT A nested JWT can be created with Rhonabwy using the following sample code: ```C #include jwt_t * jwt = NULL; jwk_t * jwk_key = NULL, * jwk_key_sign = NULL; const char payload[] = "{\"iss\":\"joe\",\"exp\":1300819380,\"http://example.com/is_root\":true}", jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}", jwk_key_str[] = "{\"kty\":\"oct\",\"k\":\"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow\"}"; char * token = NULL; if (r_jwk_init(&jwk_key) == RHN_OK && r_jwk_init(&jwk_key_sign) == RHN_OK && r_jwt_init(&jwt) == RHN_OK && r_jwk_import_from_json_str(jwk_key, jwk_pubkey_rsa_str) == RHN_OK && r_jwk_import_from_json_str(jwk_key_sign, jwk_key_str) == RHN_OK && r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5) == RHN_OK && r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC) == RHN_OK && r_jwt_set_sign_alg(jwt, R_JWA_ALG_HS256) == RHN_OK && r_jwt_set_sign_alg(jwt, R_JWA_ALG_HS256) == RHN_OK && r_jwt_set_full_claims_json_str(jwt, payload) == RHN_OK) { token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, jwk_key_sign, 0, jwk_key, 0); // token will store the nested token } r_free(token); r_jwt_free(jwt); r_jwk_free(jwk_key); ``` ### Parse a JWT The functions `r_jwt_parse` and `r_jwt_parsen` will parse a serialized JWT. If public keys are present in the header, they will be added to the public keys list and can be used to verify the token signature. ```C /** * Parses the serialized JWT in all modes (compact, flattened or general) * @param jwt: the jwt_t to update * @param jwt_str: the serialized JWT to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parse(jwt_t * jwt, const char * jwt_str, int x5u_flags); /** * Parses the serialized JWT in all modes (compact, flattened or general) * @param jwt: the jwt_t to update * @param jwt_str: the serialized JWT to parse * @param jwt_str_len: the length of jwt_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parsen(jwt_t * jwt, const char * jwt_str, size_t jwt_str_len, int x5u_flags); ``` ### Advanced parsing JWT standard allows to add in the JWT header a public key in several forms: - `jwk`: a public key in JWK format - `jku`: an url to a JWK Set - `x5c`: an array of X509 certificates - `x5u`: an url to a X509 certificate When using the functions `r_jwt_parse`, `r_jwt_parsen`, `r_jwt_compact_parse`, `r_jwt_compact_parsen`, `r_jwt_parse_unsecure`, `r_jwt_parsen_unsecure`, `r_jwt_compact_parsen_unsecure` and `r_jwt_compact_parse_unsecure`, by default, if a public key is mentionned in the header, it will be added to the `jwt->jwks_pubkey`, so the signature verification will not need to specify a key. This can be dangerous if the token comes from a untrustworthy source and if the token isn't checked properly. To simplify secure token parsing, you should use the functions `r_jwt_advanced_parse[n]`: ```C /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_advanced_parse(jwt_t * jwt, const char * token, uint32_t parse_flags, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT * @param token_len: token length * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_advanced_parsen(jwt_t * jwt, const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags); ``` ### Quick parsing The quick parsing functions can be used to parse a JWT in one line: ```C /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwt_t * r_jwt_quick_parse(const char * token, uint32_t parse_flags, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param token_len: token length * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwt_t * r_jwt_quick_parsen(const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags); ``` ### Unsecured JWT It's possible to use Rhonabwy for unsecured JWT, with the header `alg:"none"` and an empty signature, using a dedicated set of functions: `r_jwt_parse_unsecure`, `r_jwt_parsen_unsecure` and `r_jwt_serialize_signed_unsecure`, or using `r_jwt_advanced_parse` with the `parse_flags` value `R_PARSE_UNSIGNED` set. #### Parse a unsecured JWT By default, the functions `r_jwt_parse` and `r_jwt_parsen` will return `RHN_ERROR_INVALID` if the parsed JWT is unsigned. To parse any JWT, signed or unsigned, you must use the functions `r_jwt_parse_unsecure` and `r_jwt_parsen_unsecure`, or using `r_jwt_advanced_parse` with the `parse_flags` value `R_PARSE_UNSIGNED` set. #### Serialize an unsecured JWT Use the function `r_jwt_serialize_signed_unsecure` to serialize an unsecured JWT. #### Signature verification The function `r_jwt_verify_signature` will return `RHN_ERROR_INVALID` if the JWT is unsecured. #### Nested JWT with an unsecured signature It's not possible to serialize or parse a nested JWT with an unsecured signature. ## JWS A JWS (JSON Web Signature) is a content digitally signed and serialized in a compact or JSON format that can be easily transferred in HTTP requests. A compact JWS has 3 elements serialized in base64url format and separated by a dot (.). The 3 elements are: - A header in JSON format - A Payload - A digital signature Its representation uses the following format: BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature) The signature is based on the following data: BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) The algorithms supported by Rhonabwy are: - HMAC with SHA-2 Functions: `HS256`, `HS384`, `HS512` - Digital Signature with RSASSA-PKCS1-v1_5: `RS256`, `RS384`, `RS512` - Digital Signature with ECDSA: `ES256`, `ES384`, `ES512`, `ES256K` - Digital Signature with RSASSA-PSS: `PS256`, `PS384`, `PS512` - Digital Signature with Ed25519 or Ed448 Elliptic Curve: `EDdSA` - Unsecured: `none` ### Set values To set the values of the JWS (header, keys, payload, etc.), you can use the dedicated functions (see the documentation), or use the function `r_jws_set_properties` to set multiple properties at once. The option list MUST end with the option `RHN_OPT_NONE`. ```C /** * Add multiple properties to the jws_t * * @param jws: the jws_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jws_set_properties(jws_t * jws, ...); ``` The available `rhn_opt` and their following values for a `jws_t` are: ```C RHN_OPT_HEADER_INT_VALUE, const char *, int RHN_OPT_HEADER_RHN_INT_VALUE, const char *, rhn_int_t RHN_OPT_HEADER_STR_VALUE, const char * const char * RHN_OPT_HEADER_JSON_T_VALUE, const char *, json_t * RHN_OPT_HEADER_FULL_JSON_T, json_t * RHN_OPT_HEADER_FULL_JSON_STR, const char * RHN_OPT_PAYLOAD, const unsigned char *, size_t RHN_OPT_SIG_ALG, jwa_alg RHN_OPT_SIGN_KEY_JWK, jwk_t * RHN_OPT_SIGN_KEY_JWKS, jwks_t * RHN_OPT_SIGN_KEY_GNUTLS, gnutls_privkey_t RHN_OPT_SIGN_KEY_JSON_T, json_t * RHN_OPT_SIGN_KEY_JSON_STR, const char * RHN_OPT_SIGN_KEY_PEM_DER, uint, const unsigned char *, size_t RHN_OPT_VERIFY_KEY_JWK, jwk_t * RHN_OPT_VERIFY_KEY_JWKS, jwks_t * RHN_OPT_VERIFY_KEY_GNUTLS, gnutls_pubkey_t RHN_OPT_VERIFY_KEY_JSON_T, json_t * RHN_OPT_VERIFY_KEY_JSON_STR, const char * RHN_OPT_VERIFY_KEY_PEM_DER, uint, const unsigned char *, size_t ``` Example of usage for `r_jws_set_properties`: ```C jws_t * jws; const unsigned char payload[] = {4, 8, 15, 16, 23, 42}; jwk_t * jwk; // Set a private RSA key in this value r_jws_set_properties(jws, RHN_OPT_HEADER_INT_VALUE, "int", 42, RHN_OPT_HEADER_STR_VALUE, "str", "a value", RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_PAYLOAD, payload, sizeof(payload), RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_SIGN_KEY_JWK, jwk, RHN_OPT_NONE); // Test if return value is RHN_OK char * token = r_jws_serialize(jws, NULL, 0); } ``` ### JWS example In this example, the payload used is the following message: ``` The true sign of intelligence is not knowledge but imagination. ``` The JWS will be signed using HMAC with SHA256 algorithm, in this example, the signing process will use a key identified by the kid "1", therefore the header is the following: ```JSON {"alg":"HS256","kid":"1"} ``` The key used to sign the data is: ```JSON { "kty":"oct", "alg":"HS256", "k":"c2VjcmV0", "kid":"1" } ``` Finally, the complete representation of the JWS is the following: ``` eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o ``` ### Serialize a JWS using Rhonabwy in compact mode The JWS above can be created with the following sample code: ```C #include jws_t * jws = NULL; jwk_t * jwk_key_symmetric = NULL; char * token = NULL; const unsigned char payload[] = "The true sign of intelligence is not knowledge but imagination."; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0\",\"kid\":\"1\"}"; if (r_jwk_init(&jwk_key_symmetric) == RHN_OK && r_jws_init(&jws) == RHN_OK && r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str) == RHN_OK && r_jws_set_alg(jws, R_JWA_ALG_HS256) == RHN_OK && r_jws_set_payload(jws, payload, sizeof(payload)) == RHN_OK) { token = r_jws_serialize(jws, jwk_key_symmetric, 0); // token will store the signed token } r_free(token); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); ``` ### Parse and validate signature of a JWS using Rhonabwy The JWS above can be parsed and verified using the following sample code: ```C #include jws_t * jws = NULL; jwk_t * jwk_key_symmetric = NULL; const char token[] = "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ." "VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." "GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0\",\"kid\":\"1\"}"; const char * payload = NULL; size_t payload_len = 0; if (r_jwk_init(&jwk_key_symmetric) == RHN_OK && r_jws_init(&jws) == RHN_OK && r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str) == RHN_OK && r_jws_parse(jws, token, 0) == RHN_OK && r_jws_verify_signature(jws, jwk_key_symmetric, 0) == RHN_OK && (payload = r_jws_get_payload(jws, &payload_len)) != NULL && payload_len > 0) { // payload and payload_len will contain the payload data } r_jws_free(jws); r_jwk_free(jwk_key_symmetric); ``` The functions `r_jws_parse`, `r_jws_parsen`, `r_jws_compact_parse` and `r_jws_compact_parsen` will parse a serialized JWS. If public keys are present in the header, they will be added to the public keys list and can be used to verify the token signature. ```C /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parse(jws_t * jws, const char * jws_str, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags); ``` #### Compressed payload The header value `"zip":"DEF"` is used to specify if the JWS payload is compressed using [ZIP/Deflate](https://tools.ietf.org/html/rfc7516#section-4.1.3) algorithm. Rhonabwy will automatically compress or decompress the decrypted payload during serialization or parse process. ### Unsecured JWS It's possible to use Rhonabwy for unsecured JWS, with the header `alg:"none"` and an empty signature, using a dedicated set of functions: `r_jws_parse_unsecure`, `r_jws_parsen_unsecure`, `r_jws_compact_parsen_unsecure`, `r_jws_compact_parse_unsecure` and `r_jws_serialize_unsecure`, or using `r_jws_advanced_parse` with the `parse_flags` value `R_PARSE_UNSIGNED` set. #### Parse a unsecured JWS By default, the functions `r_jws_parse`, `r_jws_parsen`, `r_jws_compact_parse` and `r_jws_compact_parsen` will return `RHN_ERROR_INVALID` if the parsed JWS is unsigned. To parse any JWS, signed or unsigned, you must use the functions `r_jws_parse_unsecure`, `r_jws_parsen_unsecure`, `r_jws_compact_parsen_unsecure` and `r_jws_compact_parse_unsecure`, or using `r_jws_advanced_parse` with the `parse_flags` value `R_PARSE_UNSIGNED` set. #### Serialize an unsecured JWS Use the function `r_jws_serialize_unsecure` to serialize an unsecured JWS. By design, the functions `r_jws_serialize_json_t` and `r_jws_serialize_json_str` will return NULL with mode `R_JSON_MODE_FLATTENED` on unsecured JWS. ### Advanced parsing JWS standard allows to add in the JWS header a public key in several forms: - `jwk`: a public key in JWK format - `jku`: an url to a JWK Set - `x5c`: an array of X509 certificates - `x5u`: an url to a X509 certificate When using the functions `r_jws_parse`, `r_jws_parsen`, `r_jws_compact_parse`, `r_jws_compact_parsen`, `r_jws_parse_unsecure`, `r_jws_parsen_unsecure`, `r_jws_compact_parsen_unsecure` and `r_jws_compact_parse_unsecure`, by default, if a public key is mentionned in the header, it will be added to the `jws->jwks_pubkey`, so the signature verification will not need to specify a key. This can be dangerous if the token comes from a untrustworthy source and if the token isn't checked properly. To simplify secure token parsing, you should use the functions `r_jws_advanced_parse[n]`: ```C /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parse(jws_t * jws, const char * jws_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags); ``` ### Quick parsing The quick parsing functions can be used to parse a JWS in one line: ```C /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws_json: the serialized JWS to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jws_t * r_jws_quick_parse(const char * jws_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws_json: the serialized JWS to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jws_t * r_jws_quick_parsen(const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags); ``` #### Signature verification Signature verification is provided by the function `r_jws_verify_signature` which has the following definition: ```C /** * Verifies the signature of the JWS * The JWS must contain a signature * or the JWS must have alg: none * If the jws has multiple signatures, it will return RHN_OK if one signature matches * the public key * @param jws: the jws_t to update * @param jwk_pubkey: the public key to check the signature, * can be NULL if jws already contains a public key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_verify_signature(jws_t * jws, jwk_t * jwk_pubkey, int x5u_flags); ``` The function `r_jws_verify_signature` will return `RHN_ERROR_INVALID` if the JWS is unsecured. ## JWE A JWE (JSON Web Encryption) is an encrypted content serialized in a compact format that can be easily transferred in HTTP requests. Basically the payload is encrypted using AES-CBC or AES-GCM and an Initialization Vector (IV), a authentication tag is generated to validate the decryption, and the AES key used to encrypt the payload is encrypted itself using a symmetric or asymmetric encryption algorithm. The serialized token has the following format: BASE64URL(UTF8(JWE Protected Header)) || '.' || BASE64URL(JWE Encrypted Key) || '.' || BASE64URL(JWE Initialization Vector) || '.' || BASE64URL(JWE Ciphertext) || '.' || BASE64URL(JWE Authentication Tag) In Rhonabwy library, the supported algorithms are: - Supported Encryption Algorithm (`enc`) for JWE payload encryption: `A128CBC-HS256`, `A192CBC-HS384`, `A256CBC-HS512`, `A128GCM`, `A2192GCM`, `A256GCM` - Supported Cryptographic Algorithms for Key Management: `RSA1_5` (RSAES-PKCS1-v1_5), `RSA-OAEP`, `RSA-OAEP-256`, `A128KW`, `A192KW`, `A256KW`, `dir` (Direct use of a shared symmetric key), `A128GCMKW`, `A192GCMKW`, `A256GCMKW`, `ECDH-ES`, `ECDH-ES+A128KW`, `ECDH-ES+A192KW`, `ECDH-ES+A256KW`, `PBES2-HS384+A192KW` and `PBES2-HS512+A256KW`, `PBES2-HS256+A128KW` If you don't specify a Content Encryption Key or an Initialization Vector before the serialization, Rhonabwy will automatically generate one or the other or both depending on the algorithm specified. ### Set values To set the values of the JWE (header, keys, payload, etc.), you can use the dedicated functions (see the documentation), or use the function `r_jwe_set_properties` to set multiple properties at once. The option list MUST end with the option `RHN_OPT_NONE`. ```C /** * Add multiple properties to the jwe_t * * @param jwe: the jwe_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jwe_set_properties(jwe_t * jwe, ...); ``` The available `rhn_opt` and their following values for a `jwe_t` are: ```C RHN_OPT_HEADER_INT_VALUE, const char *, int RHN_OPT_HEADER_RHN_INT_VALUE, const char *, rhn_int_t RHN_OPT_HEADER_STR_VALUE, const char * const char * RHN_OPT_HEADER_JSON_T_VALUE, const char *, json_t * RHN_OPT_HEADER_FULL_JSON_T, json_t * RHN_OPT_HEADER_FULL_JSON_STR, const char * RHN_OPT_PAYLOAD, const unsigned char *, size_t RHN_OPT_ENC_ALG, jwa_alg RHN_OPT_ENC, jwa_enc RHN_OPT_CIPHER_KEY, const unsigned char *, size_t RHN_OPT_IV, const unsigned char *, size_t RHN_OPT_AAD, const unsigned char *, size_t RHN_OPT_ENCRYPT_KEY_JWK, jwk_t * RHN_OPT_ENCRYPT_KEY_JWKS, jwks_t * RHN_OPT_ENCRYPT_KEY_GNUTLS, gnutls_pubkey_t RHN_OPT_ENCRYPT_KEY_JSON_T, json_t * RHN_OPT_ENCRYPT_KEY_JSON_STR, const char * RHN_OPT_ENCRYPT_KEY_PEM_DER, uint, const unsigned char *, size_t RHN_OPT_DECRYPT_KEY_JWK, jwk_t * RHN_OPT_DECRYPT_KEY_JWKS, jwks_t * RHN_OPT_DECRYPT_KEY_GNUTLS, gnutls_privkey_t RHN_OPT_DECRYPT_KEY_JSON_T, json_t * RHN_OPT_DECRYPT_KEY_JSON_STR, const char * RHN_OPT_DECRYPT_KEY_PEM_DER, uint, const unsigned char *, size_t ``` Example of usage for `r_jwe_set_properties`: ```C jwe_t * jwe; const unsigned char payload[] = {4, 8, 15, 16, 23, 42}; jwk_t * jwk; // Set a public RSA key in this value r_jwe_set_properties(jwe, RHN_OPT_HEADER_INT_VALUE, "int", 42, RHN_OPT_HEADER_STR_VALUE, "str", "a value", RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_PAYLOAD, payload, sizeof(payload), RHN_OPT_ENC_ALG, R_JWA_ALG_RSA_OAEP_256, RHN_OPT_ENC, R_JWA_ENC_A128GCM, RHN_OPT_ENCRYPT_KEY_JWK, jwk, RHN_OPT_NONE); // Test if return value is RHN_OK char * token = r_jwe_serialize(jwe, NULL, 0); } ``` ### JWE example In this example, the payload used is the following message: ``` The true sign of intelligence is not knowledge but imagination. ``` The RSA private key associated to this token is: ```JSON { "kty":"RSA", "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw", "e":"AQAB", "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q", "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs","q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk", "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0","dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk", "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU", "kid":"2011-04-29" } ``` The encryption algorithm used is `A128CBC-HS256` and the cryptographic algorithm to encrypt the key is `RSA1_5` Finally, the complete representation of the JWE is: ``` eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.0ouvmluqT8kvBCgjMw8mhBFFEI5Rua58WnnATU21RqEQ2f9M6FqGEkgYpJ81ePtTkOyW1l8V-4nxIDxy-xeTHd0v5bDEbxhWKRdOmUHACC018Gt1ZB9EHHJt7k4UYj3up2xVa8qykKbZ3WGF0Gffi6ctfLCfRCWNnXMbAylV02mf4Tfhpad_WC4EeZENNryilXbAKD_9NNje-CoXD0IQK4-z2fkzfyUislwzK7dyz--uNNAC3N6XO3Blr_z61wXWGEHBa62fyHCsQqagAzN_MqTZv6cxOpRpeWM4_SwjjvcyC77rRyVpN0lC9ukyX_pNrGLXW8zH4mH78OcKPoDLPw.o5e-xb5ZzvZA2JYD2qgFbA.YNTPRS7Hv0fqE7ReEUAS_KNM31wMPPldhBGmYuQTzUWVcX8pGqooTbwaV4o_7BBiF4apD_VCGWwQ-fDD0eDofg.uyAjCu7WSo8BeBDFmYfkLA ``` ### Serialize a JWE using Rhonabwy The JWE above can be created with the following sample code: ```C #include jwe_t * jwe = NULL; jwk_t * jwk_key_rsa = NULL; char * token = NULL; const unsigned char payload[] = "The true sign of intelligence is not knowledge but imagination."; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}", if (r_jwk_init(&jwk_key_rsa) == RHN_OK && r_jwe_init(&jwe) == RHN_OK && r_jwk_import_from_json_str(jwk_key_rsa, jwk_pubkey_rsa_str) == RHN_OK && r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5) == RHN_OK && r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC) == RHN_OK && r_jwe_set_payload(jwe, payload, sizeof(payload)) == RHN_OK) { token = r_jwe_serialize(jwe, jwk_key_rsa, 0); // token will store the encrypted token } r_free(token); r_jwe_free(jwe); r_jwk_free(jwk_key_rsa); ``` #### Compressed payload The header value `"zip":"DEF"` is used to specify if the JWE payload is compressed using [ZIP/Deflate](https://tools.ietf.org/html/rfc7516#section-4.1.3) algorithm. Rhonabwy will automatically compress or decompress the decrypted payload during encryption or decryption process. ### Parse and decrypt a JWE using Rhonabwy The JWE above can be parsed and verified using the following sample code: ```C #include jwe_t * jwe = NULL; jwk_t * jwk_key_rsa = NULL; const char jwk_pirvkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}", token[] = "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.0ouvmluqT8kvBCgjMw8mhBFFEI5Rua58WnnATU21RqEQ2f9M6FqGEkgYpJ81ePtTkOyW1l8V-4nxIDxy-xeTHd0v5bDEbxhWKRdOmUHACC018Gt1ZB9EHHJt7k4UYj3up2xVa8qykKbZ3WGF0Gffi6ctfLCfRCWNnXMbAylV02mf4Tfhpad_WC4EeZENNryilXbAKD_9NNje-CoXD0IQK4-z2fkzfyUislwzK7dyz--uNNAC3N6XO3Blr_z61wXWGEHBa62fyHCsQqagAzN_MqTZv6cxOpRpeWM4_SwjjvcyC77rRyVpN0lC9ukyX_pNrGLXW8zH4mH78OcKPoDLPw.o5e-xb5ZzvZA2JYD2qgFbA.YNTPRS7Hv0fqE7ReEUAS_KNM31wMPPldhBGmYuQTzUWVcX8pGqooTbwaV4o_7BBiF4apD_VCGWwQ-fDD0eDofg.uyAjCu7WSo8BeBDFmYfkLA"; const char * payload = NULL; size_t payload_len = 0; if (r_jwk_init(&jwk_key_rsa) == RHN_OK && r_jwe_init(&jwe) == RHN_OK && r_jwk_import_from_json_str(jwk_key_rsa, jwk_pirvkey_rsa_str) == RHN_OK && r_jwe_parse(jwe, token, 0) == RHN_OK && r_jwe_decrypt(jwe, jwk_key_rsa, 0) == RHN_OK && (payload = r_jwe_get_payload(jwe, &payload_len)) != NULL && payload_len > 0) { // payload and payload_len will contain the payload data } r_jwe_free(jwe); r_jwk_free(jwk_key_rsa); ``` ### ECDH-ES implementation The ECDH-ES algorithm requires an ECC or ECDH public key for the encryption. The RFC specifies `"A new ephemeral public key value MUST be generated for each key agreement operation.", so an ephemeral key is genererated on each encryption. You can specify the ephemeral key to use though, by setting an encryption key to the JWE before generating the token. The responsibilty not to reuse the same ephemeral key is yours then. Example with a specified ephemeral key: ```C const unsigned char payload[] = "The true sign of intelligence is not knowledge but imagination..."; // This is the ephemeral key const char eph[] = " {\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0\"," "\"y\":\"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps\",\"d\":\"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo\"}", bob[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ\"," "\"y\":\"e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck\"}"; // This is the public key jwk_t * jwk_eph = NULL, * jwk_bob = NULL; jwe_t * jwe = NULL; char * token; jwk_eph = r_jwk_quick_import(R_IMPORT_JSON_STR, eph); jwk_bob = r_jwk_quick_import(R_IMPORT_JSON_STR, bob); r_jwe_init(&jwe); r_jwe_set_payload(jwe, payload, sizeof(payload)); r_jwe_add_keys(jwe, jwk_eph, jwk_bob); // Add both public and ephemeral keys here r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW); r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM); r_jwe_set_header_str_value(jwe, "apu", "QWxpY2U"); r_jwe_set_header_str_value(jwe, "apv", "Qm9i"); token = r_jwe_serialize(jwe, NULL, 0); // token will contain the compact representation of the serialized token, e.g. eyJhcHUiOiJRV3hwWTJVIiwiYXB2IjoiUW0[...] r_free(token); r_jwk_free(jwk_eph); r_jwk_free(jwk_bob); r_jwe_free(jwe); ``` ## Tokens in JSON format Rhonabwy supports serializing and parsing tokens in JSON format, see [JWE JSON Serialization](https://datatracker.ietf.org/doc/html/rfc7516#section-7.2) and [JWS JSON Serialization](https://datatracker.ietf.org/doc/html/rfc7515#section-7.2). ### JWS JSON serialization and parsing To serialize a JWS in JSON format, you must use the functions `r_jws_serialize_json_t` or `r_jws_serialize_json_str`, the parameter `mode` must have the value `R_JSON_MODE_GENERAL` to serialize in general format (allows multiple signatures), or `R_JSON_MODE_FLATTENED` to serialize in flattened format. To parse a JWS in JSON format, you can either use `r_jws_parse_json_str`, `r_jws_parsen_json_str` or `r_jws_parse_json_t` when you know the token is in JSON format, or you can use `r_jws_parse` or `r_jws_parsen`. If the token is in general JSON format and has multiple signatures, the function `r_jws_verify_signature` will return `RHN_OK` if one of the signatures is verified by the public key specified or one of the public keys added to its public JWKS. ### JWE JSON serialization and parsing To serialize a JWE in JSON format, you must use the functions `r_jwe_serialize_json_t` or `r_jwe_serialize_json_str`, the parameter `mode` must have the value `R_JSON_MODE_GENERAL` to serialize in general format (allows multiple key encryption), or `R_JSON_MODE_FLATTENED` to serialize in flattened format. To parse a JWE in JSON format, you can either use `r_jwe_parse_json_str`, `r_jwe_parsen_json_str` or `r_jwe_parse_json_t` when you know the token is in JSON format, or you can use `r_jwe_parse` or `r_jwe_parsen`. If the token is in general JSON format and has multiple key encryption, the function `r_jwe_decrypt` will decrypt the payload and return `RHN_OK` if one of the recipients content is correctly decrypted using a specified private key or one of the private key added to its private JWKS. ### Quick parsing The quick parsing functions can be used to parse a JWE in one line: ```C /** * Parses the serialized JWE in all modes (compact, flattened or general) * @param jwe_json: the serialized JWE to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwe_t * r_jwe_quick_parse(const char * jwe_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWE in all modes (compact, flattened or general) * @param jwe_json: the serialized JWE to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwe_t * r_jwe_quick_parsen(const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags); ``` rhonabwy-1.1.13/CHANGELOG.md000066400000000000000000000200121452472117100152360ustar00rootroot00000000000000# Rhonabwy Changelog ## 1.1.13 - rnbyc: Serialize alg in JWK mode when using existing keys (Thanks @sjoerdsimons) - rnbyc: check the validity of `enc` and `alg` parameters - Set arbitrary download limit to 4MB - Fix `r_jwt_validate_claims` when claim `aud` is an array of strings (Thanks @spaceone) - Add claim `R_JWT_CLAIM_AMR` - cmake: split package build options in 3 (tar.gz, deb and rpm), and set all packages build to off by default ## 1.1.12 - Fix the K for enc=AxxxCBC with alg=ECDH-ES for jwe (#28) - cmake: remove `DownloadProject` feature, now dependencies must be previously installed - Improve cmake script ## 1.1.11 - Check payload length is a multiple of block size before decrypting a jwe to avoid issues with old GnuTLS version (#24) ## 1.1.10 - Build with flag `-Wconversion` - Small refactor ## 1.1.9 - Minor bugfixes - Add test cases ## 1.1.8 - Fix build for 32 bits architectures - Remove EC P-521 support for JWE ECDH-ES key management ## 1.1.7 - Do not ignore whitespaces when parsing tokens - Enforce key verification - Security: Fix RSA-OAEP decryption key length check ([CVE-2022-38493](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-38493)) - Add examples ## 1.1.6 - Fix pkg-config file with absolute path for `CMAKE_INSTALL_{INCLUDE,LIB}DIR` - Fix `CMAKE_MODULE_PATH` who was used as single value - Security: Fix possible buffer overflow on Key unwrapping with JWE AES GCM ([CVE-2022-32096](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32096)) ## 1.1.5 - Improve jws and jwe parsing ## 1.1.4 - Bugfixes - Add `-S --self-signed` option to rnbyc to verify signatures when the public key is in included the header ## 1.1.3 - Bugfixes - Add `r_jwt_token_type` and `r_jwt_token_typen` - Replace `uint` with `unsigned int` ## 1.1.2 - Upgrade rnbyc version to 1.0 - Fix bug in `r_jwk_import_from_gnutls_privkey` for ECDSA keys ## 1.1.1 - Add `r_jwk_match_json_t` and `r_jwk_match_json_str` - Add `r_jwks_search_json_t` and `r_jwks_search_json_str` - Add option `R_X509_TYPE_UNSPECIFIED` for `r_jwk_import_from_pem_der` parameter `type` - Add options `RHN_OPT_HEADER_RHN_INT_VALUE` and `RHN_OPT_CLAIM_INT_VALUE` to set `rhn_int_t values in `r_jwx_set_properties` ## 1.1.0 - Add advanced parsing functions - Add quick_parse functions - Add `r_jwk_quick_import` and `r_jwks_quick_import` - rnbyc: update `-H` option, no value is necessary ## 1.0.0 - Use type `rhn_int_t` for integer property values instead of `int` - Rename `r_jwks_import_from_str` to `r_jwks_import_from_json_str` - Fix `kty` bugs with JWKs - Fix bug with `r_jwe_compute_hmac_tag` to work with AES-CBC keys larger than 32 bytes (Thanks wbanga!) - Force using `*_unsecure` functions to manage unsecured JWS or JWT with no signature - Use Nettle's `ecc_point_mul` instead of GnuTLS' ECDH implementation - Add macro `RHONABWY_CHECK_VERSION` - Rename `R_KEY_TYPE_ECDSA` to `R_KEY_TYPE_EC` ## 0.9.9999 - Support JSON format for JWE and JWS - Improve JWKS import - Improve `r_jwk_extract_pubkey` by copying properties `x5c`, `x5u`, `x5t` and `x5t#S256` to the public keys - Fix `AES-GCM` encryption by removing padding - Add `r_jws_set_properties`, `r_jwe_set_properties`, `r_jwt_set_properties` - Add `r_jws_set_full_header_json_t`, `r_jws_set_full_header_json_str` - Add `r_jwe_set_full_header_json_t`, `r_jwe_set_full_header_json_str` - Add `r_jwt_set_full_header_json_t`, `r_jwt_set_full_header_json_str` - Add `r_jwt_set_enc_cypher_key`, `r_jwt_get_enc_cypher_key`, `r_jwt_generate_enc_cypher_key` - Add `r_jwt_set_enc_iv`, `r_jwt_get_enc_iv` - Add `r_jwt_set_claims` - Add `r_jwe_serialize_json_str`, `r_jwe_serialize_json_t`, `r_jwe_parse_json_str`, `r_jwe_parse_json_t` - Add `r_jwe_compact_parsen`, `r_jwe_compact_parse` to parse JWE in compact mode - Add `r_jwe_parse_json_str`, `r_jwe_parsen_json_str`, `r_jwe_parse_json_t` to parse JWE in JSON mode - Improve `r_jwe_decrypt` and `r_jwe_decrypt_key` to support JWE serialized in General JSON format with multiple recipients - Add `r_jws_serialize_json_str`, `r_jws_serialize_json_t`, `r_jws_parse_json_str`, `r_jws_parse_json_t` - Add `r_jws_compact_parsen`, `r_jws_compact_parse` to parse JWS in compact mode - Add `r_jws_parse_json_str`, `r_jws_parsen_json_str`, `r_jws_parse_json_t` to parse JWS in JSON mode - Improve `r_jws_verify_signature` to support JWS serialized in General JSON format with multiple signatures - Allow deflate payload in JWS with header property `{zip:"DEF"}` ## 0.9.999 - Remove `ES256K` signature algorithm support - Implement `r_jwt_get_sig_kid`, `r_jwt_get_enc_kid`, `r_jwe_get_kid`, `r_jws_get_kid` ## 0.9.99 - Fix get symmetric key length - Implement CEK `A128KW`, `A192KW` and `A256KW` - Fix `r_library_info_json_t` output because `A***GCMKW` were supported before, not `A***KW` - Implement CEK `PBES2-HS256+A128KW`, `PBES2-HS384+A192KW`, `PBES2-HS512+A256KW` - Implement CEK `RSA-OAEP`, `RSA-OAEP-256` - Implement CEK `ECDH-ES`, `ECDH-ES+A128KW`, `ECDH-ES+A192KW`, `ECDH-ES+A256KW` - Implement signature algorithm `ES256K` - Add `r_jwk_import_from_password` - Allow to disable ulfius if not needed ## 0.9.13 - Add `r_jwk_thumbprint`, thumbprint of a jwk_t based on the RFC 7638 - Test `x5c` validity on `r_jwk_is_valid` - Breaking changes: refactor functions `r_jwk_import_from_x5u`, `r_jwks_export_to_gnutls_privkey` and `r_jwk_export_to_gnutls_privkey` - Add `r_jwk_is_valid_x5u` to check the validity of a remote certificate - Add `r_jwk_validate_x5c_chain` to validate the full `x5c` or `x5u` chain - Bugfixes ## 0.9.12 - Add rnbyc manpage - Small bugfixes ## 0.9.11 - Support `A192GCMKW` and `A192GCM` with GnuTLS >= 3.6.14 - Add command-line program `rnbyc` to generate, parse and serialize keys (JWK, JWKS) and tokens (JWT) - Remove whitespaces on token parse - Fix default header value `typ` in a JWT ## 0.9.10 - Do not overwrite header value `typ` in a JWT if one is already set - Small bugfixes - Add function `r_jwk_export_to_gnutls_crt` - Add `x5c` when importing certificate - Fix AES GCM encryption/decryption ## 0.9.9 - Fix JWE payload encryption with AES-GCM - Add `x5u_flag` value `R_FLAG_IGNORE_REMOTE` to avoid downloading remote keys if not required - Add functions `r_jwt_set_full_claims_json_str`, `r_jwt_get_type`, `r_jwa_alg_to_str`, `r_jwa_enc_to_str` - Add API documentation - Add support for key management algorithms `A128GCMKW` and `A256GCMKW` - Add functions `r_jwt_decrypt_nested`, `r_jwt_verify_signature_nested`, `r_jwt_parsen`, `r_jwe_parsen` and `r_jws_parsen` - Add function `r_jwt_validate_claims` to validate claims - Add functions `r_jw[se]_add_keys_json_str`, `r_jw[se]_add_keys_json_t`, `r_jw[se]_add_keys_pem_der`, `r_jw[se]_add_keys_gnutls`, `r_jw[se]_add_key_symmetric` - Add functions `r_jwt_add_[sign|enc]_keys_json_str`, `r_jwt_add_[sign|enc]_keys_json_t`, `r_jwt_add_[sign|enc]_keys_pem_der`, `r_jwt_add_[sign|enc]_keys_gnutls`, `r_jwt_add_[sign|enc]_key_symmetric` ## 0.9.8 - Add [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) support - Another set of refactoring ## 0.9.7 - Add [JSON Web Encryption](https://tools.ietf.org/html/rfc7516) (JWE) support - Refactor functions names - Add `r_library_info_json_t`, `r_library_info_json_str` and `r_free` ## 0.9.6 - Add [JSON Web Signature](https://tools.ietf.org/html/rfc7515) (JWS) support - Add `r_jwk_import_from_x5u`, `r_jwk_import_from_symmetric_key`, `r_jwk_export_to_symmetric_key` - Add `r_jwk_copy`, `r_jwk_equal` - Add `r_jwks_copy`, `r_jwks_equal` and `r_jwks_empty` - Rename functions `r_init_???` to `r_???_init` and `r_free_???` to r_???_free` to be consistent ## 0.9.5 - Add `r_jwks_get_by_kid` - Rename flags `R_X5U_FLAG_IGNORE_SERVER_CERTIFICATE` and `R_X5U_FLAG_FOLLOW_REDIRECT` to `R_FLAG_IGNORE_SERVER_CERTIFICATE` and `R_FLAG_FOLLOW_REDIRECT` ## 0.9.4 - Add `r_jwks_import_from_uri` - Fix memory leaks ## 0.9.3 - Allow import jwks when jwks array is empty ## 0.9.2 - Parses `JWK` in `json_t *` or `char *` format - Imports `gnutls`, `PEM` or `DER` keys to `JWK` - Exports `JWK` to `json_t *`, `char *`, `gnutls`, `PEM` or `DER` - Retrieves and extract keys in `x5c` or `x5u` fields - Manages `JWKS` as a set of `JWK` rhonabwy-1.1.13/CMakeLists.txt000066400000000000000000000412261452472117100161770ustar00rootroot00000000000000# # Rhonabwy library # # CMake file used to build all programs # # Copyright 2018 Silvio Clecio # Copyright 2021-2023 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the MIT License # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # cmake_minimum_required(VERSION 3.5) project(rhonabwy C) set(CMAKE_C_STANDARD 99) if (NOT MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") endif() # library info set(RHONABWY_LIBS ) set(PROJECT_DESCRIPTION "Javascript Object Signing and Encryption (JOSE) library - JWK, JWKS, JWS, JWE and JWT") set(PROJECT_HOMEPAGE_URL "https://github.com/babelouest/rhonabwy/") set(PROJECT_BUGREPORT_PATH "https://github.com/babelouest/rhonabwy/issues") set(LIBRARY_VERSION_MAJOR "1") set(LIBRARY_VERSION_MINOR "1") set(LIBRARY_VERSION_PATCH "13") set(ORCANIA_VERSION_REQUIRED "2.3.3") set(YDER_VERSION_REQUIRED "1.4.20") set(ULFIUS_VERSION_REQUIRED "2.7.15") set(PROJECT_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(PROJECT_VERSION_MAJOR ${LIBRARY_VERSION_MAJOR}) set(PROJECT_VERSION_MINOR ${LIBRARY_VERSION_MINOR}) set(PROJECT_VERSION_PATCH ${LIBRARY_VERSION_PATCH}) if (${LIBRARY_VERSION_MAJOR} VERSION_LESS 10) set (LIBRARY_VERSION_MAJOR_PAD "0${LIBRARY_VERSION_MAJOR}") else () set (LIBRARY_VERSION_MAJOR_PAD "${LIBRARY_VERSION_MAJOR}") endif () if (${LIBRARY_VERSION_MINOR} VERSION_LESS 10) set (LIBRARY_VERSION_MINOR_PAD "0${LIBRARY_VERSION_MINOR}") else () set (LIBRARY_VERSION_MINOR_PAD "${LIBRARY_VERSION_MINOR}") endif () if (${LIBRARY_VERSION_PATCH} VERSION_LESS 10) set (LIBRARY_VERSION_PATCH_PAD "0${LIBRARY_VERSION_PATCH}") else () set (LIBRARY_VERSION_PATCH_PAD "${LIBRARY_VERSION_PATCH}") endif () set(PROJECT_VERSION_NUMBER "${LIBRARY_VERSION_MAJOR_PAD}${LIBRARY_VERSION_MINOR_PAD}${LIBRARY_VERSION_PATCH_PAD}") set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}") set(LIBRARY_SOVERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}") # cmake modules set(R_CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules) list(APPEND CMAKE_MODULE_PATH "${R_CMAKE_MODULE_PATH}") include(GNUInstallDirs) include(CheckSymbolExists) include(CMakeDependentOption) include(CMakePackageConfigHelpers) # check if _GNU_SOURCE is available if (NOT _GNU_SOURCE) check_symbol_exists(__GNU_LIBRARY__ "features.h" _GNU_SOURCE) if (NOT _GNU_SOURCE) unset(_GNU_SOURCE CACHE) check_symbol_exists(_GNU_SOURCE "features.h" _GNU_SOURCE) endif () endif () if (_GNU_SOURCE) add_definitions(-D_GNU_SOURCE) endif () include(FindJansson) set(JANSSON_MIN_VERSION 2.4) find_package(Jansson ${JANSSON_MIN_VERSION} REQUIRED) list(APPEND RHONABWY_LIBS Jansson::Jansson) include(FindNettle) find_package(Nettle REQUIRED) list(APPEND RHONABWY_LIBS Nettle::Nettle) find_package(GnuTLS REQUIRED) list(APPEND RHONABWY_LIBS GnuTLS::GnuTLS) find_package(ZLIB REQUIRED) list(APPEND RHONABWY_LIBS ZLIB::ZLIB) option(WITH_ULFIUS "Use Ulfius library to get HTTP remote content - deprecated, use WITH_CURL instead" ON) option(WITH_CURL "Use curl library to get HTTP remote content" ON) if (NOT WITH_ULFIUS) message(WARNING "Option WITH_ULFIUS is deprecated, use WITH_CURL instead") set(WITH_CURL OFF) endif () if (WITH_CURL) find_package(CURL REQUIRED) if (NOT TARGET CURL::libcurl) add_library(CURL::libcurl INTERFACE IMPORTED) set_target_properties(CURL::libcurl PROPERTIES INTERFACE_LINK_LIBRARIES "${CURL_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") endif () list(APPEND RHONABWY_LIBS CURL::libcurl) set(R_WITH_CURL ON) else () set(R_WITH_CURL OFF) endif () # directories and source set(INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) set(SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(RNBYC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tools/rnbyc) include_directories(${INC_DIR}) set(LIB_SRC ${INC_DIR}/rhonabwy.h ${SRC_DIR}/misc.c ${SRC_DIR}/jwk.c ${SRC_DIR}/jwks.c ${SRC_DIR}/jws.c ${SRC_DIR}/jwe.c ${SRC_DIR}/jwt.c) set(PKGCONF_REQ "") set(PKGCONF_REQ_PRIVATE "") # static library option(BUILD_STATIC "Build static library." OFF) if (BUILD_STATIC) add_library(rhonabwy_static STATIC ${LIB_SRC}) add_library(Rhonabwy::Rhonabwy-static ALIAS rhonabwy_static) target_include_directories(rhonabwy_static PUBLIC "$" PUBLIC "$" PUBLIC "$") target_link_libraries(rhonabwy_static PUBLIC ${RHONABWY_LIBS}) target_compile_definitions(rhonabwy_static PUBLIC O_STATIC_LIBRARY) set_target_properties(rhonabwy_static PROPERTIES PUBLIC_HEADER "${INC_DIR}/rhonabwy.h;${PROJECT_BINARY_DIR}/rhonabwy-cfg.h" OUTPUT_NAME rhonabwy EXPORT_NAME Rhonabwy-static) if (MSVC) set_target_properties(rhonabwy_static PROPERTIES OUTPUT_NAME rhonabwy-static) endif () if (NOT MSVC) target_compile_options(rhonabwy_static PRIVATE -Wextra -Wconversion) endif () set(rhonabwy_lib rhonabwy_static) endif () # shared library add_library(rhonabwy SHARED ${LIB_SRC}) add_library(Rhonabwy::Rhonabwy ALIAS rhonabwy) target_include_directories(rhonabwy PUBLIC "$" PUBLIC "$" PUBLIC "$") target_link_libraries(rhonabwy PUBLIC ${RHONABWY_LIBS}) set_target_properties(rhonabwy PROPERTIES PUBLIC_HEADER "${INC_DIR}/rhonabwy.h;${PROJECT_BINARY_DIR}/rhonabwy-cfg.h" VERSION "${LIBRARY_VERSION}" SOVERSION "${LIBRARY_SOVERSION}" WINDOWS_EXPORT_ALL_SYMBOLS TRUE EXPORT_NAME Rhonabwy) if (WIN32) set_target_properties(rhonabwy PROPERTIES SUFFIX "-${LIBRARY_VERSION_MAJOR}.dll") endif () if (NOT MSVC) target_compile_options(rhonabwy PRIVATE -Wextra -Wconversion) endif() set(rhonabwy_lib rhonabwy) find_package(Orcania ${ORCANIA_VERSION_REQUIRED} REQUIRED) if ("${ORCANIA_VERSION_STRING}" VERSION_GREATER_EQUAL "${ORCANIA_VERSION_REQUIRED}") message(STATUS "Orcania found: ${ORCANIA_VERSION_STRING}") else () message( FATAL_ERROR "Orcania version required: ${ORCANIA_VERSION_REQUIRED} - version installed: ${ORCANIA_VERSION_STRING}") endif () target_link_libraries(rhonabwy PUBLIC $) if (BUILD_STATIC) if(TARGET Orcania::Orcania-static) target_link_libraries(rhonabwy_static PUBLIC $) else() target_link_libraries(rhonabwy_static PUBLIC $) endif() endif () find_package(Yder ${YDER_VERSION_REQUIRED} REQUIRED) if ("${YDER_VERSION_STRING}" VERSION_GREATER_EQUAL "${YDER_VERSION_REQUIRED}") message(STATUS "Yder found: ${YDER_VERSION_STRING}") else () message( FATAL_ERROR "Yder version required: ${YDER_VERSION_REQUIRED} - version installed: ${YDER_VERSION_STRING}") endif () target_link_libraries(rhonabwy PUBLIC $) if (BUILD_STATIC) if(TARGET Yder::Yder-static) target_link_libraries(rhonabwy_static PUBLIC $) else() target_link_libraries(rhonabwy_static PUBLIC $) endif() endif () # build rnbyc option(BUILD_RNBYC "Build rnbyc application." ON) if (BUILD_RNBYC) add_executable(rnbyc ${RNBYC_DIR}/rnbyc.c ${INC_DIR}/rhonabwy.h ${PROJECT_BINARY_DIR}/rhonabwy-cfg.h) set_target_properties(rnbyc PROPERTIES SKIP_BUILD_RPATH TRUE COMPILE_OPTIONS "-Wextra;-Wconversion") add_dependencies(rnbyc rhonabwy) target_link_libraries(rnbyc rhonabwy ${RHONABWY_LIBS} Yder::Yder Orcania::Orcania) install(TARGETS rnbyc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${RNBYC_DIR}/rnbyc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT runtime) endif () # documentation option(BUILD_RHONABWY_DOCUMENTATION "Build the documentation." OFF) if (BUILD_RHONABWY_DOCUMENTATION) find_package(Doxygen) if (DOXYGEN_FOUND) set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/doc/doxygen.cfg) set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/doxyfile) configure_file(${doxyfile_in} ${doxyfile} @ONLY) add_custom_target(doc COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile_in} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Generating documentation with Doxygen" VERBATIM) else () message(FATAL_ERROR "Doxygen is needed to build the documentation.") endif () endif () # build rhonabwy-cfg.h file configure_file(${INC_DIR}/rhonabwy-cfg.h.in ${PROJECT_BINARY_DIR}/rhonabwy-cfg.h) set (CMAKE_EXTRA_INCLUDE_FILES ${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR}) # tests option(BUILD_RHONABWY_TESTING "Build the testing tree." OFF) # because we do not use include(CTest) if (BUILD_RHONABWY_TESTING) find_package(Check REQUIRED) if (CHECK_FOUND) if (NOT WIN32 AND NOT APPLE) include(FindSubunit) find_package(Subunit REQUIRED) endif () enable_testing() set(CMAKE_CTEST_COMMAND ctest -V) set(TEST_LIBS ) set(TST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test) list(APPEND TEST_LIBS Rhonabwy::Rhonabwy) list(APPEND TEST_LIBS Check::Check) if (NOT WIN32) find_package(Threads REQUIRED) list(APPEND TEST_LIBS ${CMAKE_THREAD_LIBS_INIT} m) endif () if (NOT APPLE AND NOT WIN32) list(APPEND TEST_LIBS rt) endif () if (NOT WIN32 AND NOT APPLE) list(APPEND TEST_LIBS Subunit::Subunit) endif () set(TESTS misc cookbook jwk_core jwk_export jwk_import jwks_core jws_core jws_hmac jws_ecdsa jws_rsa jws_rsapss jws_json jwe_core jwe_rsa jwe_aesgcm jwe_dir jwe_kw jwe_rsa_oaep jwe_ecdh jwe_pbes2 jwe_json jwt_core jwt_encrypt jwt_sign jwt_nested ) find_package(Ulfius ${ULFIUS_VERSION_REQUIRED} REQUIRED) if ("${ULFIUS_VERSION_STRING}" VERSION_GREATER_EQUAL "${ULFIUS_VERSION_REQUIRED}") message(STATUS "Ulfius found: ${ULFIUS_VERSION_STRING}") else () message( FATAL_ERROR "Ulfius version required: ${ULFIUS_VERSION_REQUIRED} - version installed: ${ULFIUS_VERSION_STRING}") endif () list(APPEND TEST_LIBS Ulfius::Ulfius) configure_file( "${R_CMAKE_MODULE_PATH}/CTestCustom.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake" @ONLY) foreach (t ${TESTS}) add_executable(${t} EXCLUDE_FROM_ALL ${TST_DIR}/${t}.c) target_include_directories(${t} PRIVATE ${TST_DIR}) target_link_libraries(${t} PRIVATE ${TEST_LIBS}) add_test(NAME ${t} WORKING_DIRECTORY ${TST_DIR} COMMAND ${t}) endforeach () endif () endif () # install target option(INSTALL_HEADER "Install the header files" ON) # Install rhonabwy.h or not if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") set(PKGCONFIG_TARGET_INCLUDES "${CMAKE_INSTALL_INCLUDEDIR}") else() set(PKGCONFIG_TARGET_INCLUDES "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") set(PKGCONFIG_TARGET_LIBDIR "${CMAKE_INSTALL_LIBDIR}") else() set(PKGCONFIG_TARGET_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") endif() configure_file(librhonabwy.pc.in librhonabwy.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/librhonabwy.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) set(TARGETS rhonabwy) if (INSTALL_HEADER) install(TARGETS ${TARGETS} EXPORT RhonabwyExports RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) else () install(TARGETS ${TARGETS} EXPORT RhonabwyExports RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif () if (INSTALL_HEADER) set(RHONABWY_INSTALL_CMAKEDIR_DEFAULT "${CMAKE_INSTALL_LIBDIR}/cmake/Rhonabwy") if (WIN32 AND NOT MINGW) set(RHONABWY_INSTALL_CMAKEDIR_DEFAULT "cmake") endif () set(RHONABWY_INSTALL_CMAKEDIR ${RHONABWY_INSTALL_CMAKEDIR_DEFAULT} CACHE STRING "Location where to install the cmake config files") install(EXPORT RhonabwyExports DESTINATION "${RHONABWY_INSTALL_CMAKEDIR}" NAMESPACE "Rhonabwy::" FILE "RhonabwyTargets.cmake") configure_package_config_file(cmake-modules/RhonabwyConfig.cmake.in RhonabwyConfig.cmake INSTALL_DESTINATION "${RHONABWY_INSTALL_CMAKEDIR}") write_basic_package_version_file(RhonabwyConfigVersion.cmake COMPATIBILITY AnyNewerVersion) install(FILES cmake-modules/FindGnuTLS.cmake cmake-modules/FindNettle.cmake cmake-modules/FindJansson.cmake cmake-modules/FindMHD.cmake "${PROJECT_BINARY_DIR}/RhonabwyConfig.cmake" "${PROJECT_BINARY_DIR}/RhonabwyConfigVersion.cmake" DESTINATION "${RHONABWY_INSTALL_CMAKEDIR}") endif () # uninstall target if (NOT TARGET uninstall) configure_file( "${R_CMAKE_MODULE_PATH}/CMakeUninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) endif () # packaging set(CPACK_PACKAGE_VERSION_MAJOR ${LIBRARY_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${LIBRARY_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${LIBRARY_VERSION_PATCH}) if (INSTALL_HEADER) set(PACKAGE_FILE_NAME "lib${CMAKE_PROJECT_NAME}-dev_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") else () set(PACKAGE_FILE_NAME "lib${CMAKE_PROJECT_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") endif () set(PACKAGE_IGNORED_FILES "${CMAKE_CURRENT_BINARY_DIR}/;/.git/;.gitignore;~$;${CPACK_SOURCE_IGNORE_FILES}") set(CPACK_GENERATOR ) set(CPACK_PACKAGE_NAME "librhonabwy") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Handle the flow of OAuth2 and OpenID Connect authentication process from the client side") set(CPACK_PACKAGE_VERSION_MAJOR ${LIBRARY_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${LIBRARY_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${LIBRARY_VERSION_PATCH}) set(CPACK_PACKAGE_FILE_NAME ${PACKAGE_FILE_NAME}) option(BUILD_TGZ "Build a TAR.GZ for your system" OFF) if (BUILD_TGZ) list(APPEND CPACK_GENERATOR TGZ) set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME ${PACKAGE_FILE_NAME}) set(CPACK_SOURCE_IGNORE_FILES ${PACKAGE_IGNORED_FILES}) endif () option(BUILD_DEB "Build a DEB for your system" OFF) if (BUILD_DEB) list(APPEND CPACK_GENERATOR DEB) set(CPACK_DEBIAN_PACKAGE_MAINTAINER "mail@babelouest.org") set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${PROJECT_DESCRIPTION}) set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/babelouest/rhonabwy") set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.4), liborcania|liborcania-dev (>= ${ORCANIA_VERSION_REQUIRED}), libyder|libyder-dev (>= ${YDER_VERSION_REQUIRED})") endif () option(BUILD_RPM "Build a RPM for your system" OFF) if (BUILD_RPM) list(APPEND CPACK_GENERATOR RPM) set(CPACK_RPM_PACKAGE_LICENSE "LGPL") set(CPACK_RPM_PACKAGE_URL "http://babelouest.github.io/rhonabwy/") endif () include(CPack) message(STATUS "Build testing tree: ${BUILD_RHONABWY_TESTING}") message(STATUS "Install the header files: ${INSTALL_HEADER}") message(STATUS "Build CLI rnbyc: ${BUILD_RNBYC}") message(STATUS "Build Static library: ${BUILD_STATIC}") message(STATUS "Build TAR.GZ package: ${BUILD_TGZ}") message(STATUS "Build DEB package: ${BUILD_DEB}") message(STATUS "Build RPM package: ${BUILD_RPM}") message(STATUS "Build documentation: ${BUILD_RHONABWY_DOCUMENTATION}") message(STATUS "Use libcurl for remote content: ${WITH_CURL}") rhonabwy-1.1.13/LICENSE000066400000000000000000000635361452472117100144540ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. (This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.) Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. {signature of Ty Coon}, 1 April 1990 Ty Coon, President of Vice That's all there is to it! rhonabwy-1.1.13/Makefile000066400000000000000000000025611452472117100150760ustar00rootroot00000000000000# # Iddawc library # # Makefile used to build all programs # # Copyright 2020-2022 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . # LIBIDDAWC_LOCATION=./src TESTS_LOCATION=./test RNBYC_LOCATION=./tools/rnbyc all: cd $(LIBIDDAWC_LOCATION) && $(MAKE) $* cd $(RNBYC_LOCATION) && $(MAKE) $* debug: cd $(LIBIDDAWC_LOCATION) && $(MAKE) debug $* cd $(RNBYC_LOCATION) && $(MAKE) debug $* clean: cd $(LIBIDDAWC_LOCATION) && $(MAKE) clean cd $(TESTS_LOCATION) && $(MAKE) clean cd $(RNBYC_LOCATION) && $(MAKE) clean rm -rf doc/html/ install: cd $(LIBIDDAWC_LOCATION) && $(MAKE) install cd $(RNBYC_LOCATION) && $(MAKE) install uninstall: cd $(LIBIDDAWC_LOCATION) && $(MAKE) uninstall cd $(RNBYC_LOCATION) && $(MAKE) uninstall check: cd $(TESTS_LOCATION) && $(MAKE) doxygen: doxygen doc/doxygen.cfg rhonabwy-1.1.13/README.md000066400000000000000000000301531452472117100147130ustar00rootroot00000000000000# Rhonabwy - Javascript Object Signing and Encryption (JOSE) library - JWK, JWKS, JWS, JWE and JWT [![View on jwt.io](http://jwt.io/img/badge.svg)](https://jwt.io) ![C/C++ CI](https://github.com/babelouest/rhonabwy/workflows/C/C++%20CI/badge.svg) - Create, modify, parse, import or export [JSON Web Keys](https://tools.ietf.org/html/rfc7517) (JWK) and JSON Web Keys Set (JWKS) - Create, modify, parse, validate or serialize [JSON Web Signatures](https://tools.ietf.org/html/rfc7515) (JWS) - Create, modify, parse, validate or serialize [JSON Web Encryption](https://tools.ietf.org/html/rfc7516) (JWE) - Create, modify, parse, validate or serialize [JSON Web Token](https://tools.ietf.org/html/rfc7519) (JWT) JWT Relies on JWS and JWE functions, so it supports the same functionalities as the other 2. JWT functionalities also support nesting serialization (JWE nested in a JWS or the opposite). - Supported Cryptographic Algorithms (`alg`) for Digital Signatures and MACs: | "alg" Param Value | Digital Signature or MAC Algorithm | Supported | |---|---|---| | HS256 | HMAC using SHA-256 |**YES**| | HS384 | HMAC using SHA-384 |**YES**| | HS512 | HMAC using SHA-512 |**YES**| | RS256 | RSASSA-PKCS1-v1_5 using SHA-256 |**YES**| | RS384 | RSASSA-PKCS1-v1_5 using SHA-384 |**YES**| | RS512 | RSASSA-PKCS1-v1_5 using SHA-512 |**YES**| | ES256 | ECDSA using P-256 and SHA-256 |**YES**(1)| | ES384 | ECDSA using P-384 and SHA-384 |**YES**(1)| | ES512 | ECDSA using P-521 and SHA-512 |**YES**(1)| | PS256 | RSASSA-PSS using SHA-256 and MGF1 with SHA-256 |**YES**(1)| | PS384 | RSASSA-PSS using SHA-384 and MGF1 with SHA-384 |**YES**(1)| | PS512 | RSASSA-PSS using SHA-512 and MGF1 with SHA-512 |**YES**(1)| | none | No digital signature or MAC performed |**YES**| | EdDSA | Digital Signature with Ed25519 Elliptic Curve |**YES**(1)| | ES256K | Digital Signature with secp256k1 Curve Key |*NO*| (1) GnuTLS 3.6 minimum is required for ECDSA, Ed25519 (EdDSA) and RSA-PSS signatures. - Supported Encryption Algorithm (`enc`) for JWE payload encryption: | "enc" Param Value | Content Encryption Algorithm | Supported | |---|---|---| | A128CBC-HS256 | AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm, as defined in Section 5.2.3 |**YES**| | A192CBC-HS384 | AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm, as defined in Section 5.2.4 |**YES**| | A256CBC-HS512 | AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm, as defined in Section 5.2.5 |**YES**| | A128GCM | AES GCM using 128-bit key |**YES**| | A192GCM | AES GCM using 192-bit key |**YES** (2)| | A256GCM | AES GCM using 256-bit key |**YES**| (2) GnuTLS 3.6.14 minimum is required for `A192GCM` enc. - Supported Cryptographic Algorithms (`alg`) for Key Management: | "alg" Param Value | Key Management Algorithm | Supported | |---|---|---| | RSA1_5 | RSAES-PKCS1-v1_5 |**YES**| | RSA-OAEP | RSAES OAEP using default parameters |**YES**(3)| | RSA-OAEP-256 | RSAES OAEP using SHA-256 and MGF1 with SHA-256 |**YES**| | A128KW | AES Key Wrap with default initial value using 128-bit key |**YES**(3)| | A192KW | AES Key Wrap with default initial value using 192-bit key |**YES**(3)| | A256KW | AES Key Wrap with default initial value using 256-bit key |**YES**(3)| | dir | Direct use of a shared symmetric key as the CEK |**YES**| | ECDH-ES | Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF |**YES**(4)| | ECDH-ES+A128KW | ECDH-ES using Concat KDF and CEK wrapped with "A128KW" |**YES**(4)| | ECDH-ES+A192KW | ECDH-ES using Concat KDF and CEK wrapped with "A192KW" |**YES**(4)| | ECDH-ES+A256KW | ECDH-ES using Concat KDF and CEK wrapped with "A256KW" |**YES**(4)| | A128GCMKW | Key wrapping with AES GCM using 128-bit key |**YES**| | A192GCMKW | Key wrapping with AES GCM using 192-bit key |**YES**(5)| | A256GCMKW | Key wrapping with AES GCM using 256-bit key |**YES**| | PBES2-HS256+A128KW | PBES2 with HMAC SHA-256 and "A128KW" wrapping |**YES**(5)| | PBES2-HS384+A192KW | PBES2 with HMAC SHA-384 and "A192KW" wrapping |**YES**(5)| | PBES2-HS512+A256KW | PBES2 with HMAC SHA-512 and "A256KW" wrapping |**YES**(5)| (3) Nettle 3.4 minimum is required for RSA-OAEP and AES key Wrap (4) Nettle 3.6 minimum is required for ECDH-ES (5) GnuTLS 3.6.14 minimum is required for `A192GCMKW`, `PBES2-HS256+A128KW`, `PBES2-HS384+A192KW` and `PBES2-HS512+A256KW` key wrapping algorithms. # rnbyc, Rhonabwy command-line tool This command-line program can be used to: - Generate and/or parse keys and output the result in a JWKS or a public/private pair of JWKS files. - Parse, decrypt, and/or verify signature of a JWT, using given key - Serialize a JWT, the JWT can be signed, encrypted or nested Example commands to generate a RSA2048 key pair, serialize a JWT signed with the private key, then parse the serialized token and verifies the signature with the public key. ```shell $ rnbyc -j -g RSA2048 -o priv.jwks -p pub.jwks $ rnbyc -s '{"iss":"https://rhonabwy.tld","aud":"abcxyz1234"}' -K priv.jwks -a RS256 eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImVNdnI3bktBX2I5QUI4NGpMU05zTFFKZHRmdHpadnllV2M1V0VVMjhnRFkifQ.eyJpc3MiOiJodHRwczovL3Job25hYnd5LnRsZCIsImF1ZCI6ImFiY3h5ejEyMzQifQ.j6v-yxcWvHhyLIc-r3Nzn5rCF9yeJJzgyLSHW_10wREfckspbzf8UTof5Zsrwg8JvKNlJ4Tt4ZffJC4BkkehdBYXPrgcfq9NtvNYsRmAdiNJhOXtZCU9j9X89j2xhY7pRBgWENI9c3730cmAUgaC-IUKsoNRw_dd-eboyrgYKIzUCYRnuwqDB31T2oUSVjy6CckoenyoeHJhHg-x384G-g4ovP1l-L4YpjgCyr6BR8mjBFwHU56MP6hNN299HpUd56usQ3vMn7z5hL6QqE92qz-SsJBySrv8whLWjjN9J4Wq5g3_R7Qw00x60bFnuCDhPBjg3EPXXGqlI0x0vwgwHw $ rnbyc -P pub.jwks -t eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6ImVNdnI3bktBX2I5QUI4NGpMU05zTFFKZHRmdHpadnllV2M1V0VVMjhnRFkifQ.eyJpc3MiOiJodHRwczovL3Job25hYnd5LnRsZCIsImF1ZCI6ImFiY3h5ejEyMzQifQ.j6v-yxcWvHhyLIc-r3Nzn5rCF9yeJJzgyLSHW_10wREfckspbzf8UTof5Zsrwg8JvKNlJ4Tt4ZffJC4BkkehdBYXPrgcfq9NtvNYsRmAdiNJhOXtZCU9j9X89j2xhY7pRBgWENI9c3730cmAUgaC-IUKsoNRw_dd-eboyrgYKIzUCYRnuwqDB31T2oUSVjy6CckoenyoeHJhHg-x384G-g4ovP1l-L4YpjgCyr6BR8mjBFwHU56MP6hNN299HpUd56usQ3vMn7z5hL6QqE92qz-SsJBySrv8whLWjjN9J4Wq5g3_R7Qw00x60bFnuCDhPBjg3EPXXGqlI0x0vwgwHw Token signature verified { "iss": "https://rhonabwy.tld", "aud": "abcxyz1234" } ``` Check its [documentation](tools/rnbyc/README.md) # API Documentation Documentation is available in the documentation page: [https://babelouest.github.io/rhonabwy/](https://babelouest.github.io/rhonabwy/) Example program to parse and verify the signature of a JWT using its public key in JWK format: ```C /** * To compile this program run: * gcc -o demo_rhonabwy demo_rhonabwy.c -lrhonabwy */ #include #include int main(void) { const char token[] = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ." // Header "eyJzdHIiOiJwbG9wIiwiaW50Ijo0Miwib2JqIjp0cnVlfQ." // Claims "ooXNEt3JWFGMuvkGUM-szUOU1QTu4DvyC3qQP64UGeeJQuMGupBCVATnGkiqNLiPSJ9uBsjZbyUrWe8z7Iag_A"; // Signature const char jwk_pubkey_ecdsa_str[] = "{" "\"kty\":\"EC\"," "\"crv\":\"P-256\"," "\"alg\":\"ES256\"," "\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\"," "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\"," "\"kid\":\"1\"," "\"use\":\"sig\"" "}"; unsigned char output[2048]; size_t output_len = 2048; jwk_t * jwk = NULL; jwt_t * jwt = NULL; char * claims; if ((jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str)) != NULL && (jwt = r_jwt_quick_parse(token, R_PARSE_NONE, 0)) != NULL) { if (r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, output, &output_len, 0) == RHN_OK) { printf("Exported key:\n%.*s\n", (int)output_len, output); if (r_jwt_verify_signature(jwt, jwk, 0) == RHN_OK) { claims = r_jwt_get_full_claims_str(jwt); printf("Verified payload:\n%s\n", claims); r_free(claims); } else { fprintf(stderr, "Error r_jwt_verify_signature\n"); } } else { fprintf(stderr, "Error r_jwk_export_to_pem_der\n"); } } else { fprintf(stderr, "Error parsing\n"); } r_jwk_free(jwk); r_jwt_free(jwt); return 0; } ``` # Examples Some example programs are available in the [examples](examples/) directory. # Installation Rhonabwy is available in the following distributions. [![Packaging status](https://repology.org/badge/vertical-allrepos/rhonabwy.svg)](https://repology.org/project/rhonabwy/versions) ## Dependencies Rhonabwy is based on [Nettle](https://www.lysator.liu.se/~nisse/nettle/), [GnuTLS](https://www.gnutls.org/), [Jansson](http://www.digip.org/jansson/), [zlib](https://www.zlib.net/), [libcurl](https://curl.haxx.se/libcurl/) and libsystemd (if possible), you must install those libraries first before building Rhonabwy. You also need [check](https://libcheck.github.io/check/) and [Ulfius](https://github.com/babelouest/ulfius) to run the tests. ## Prerequisites You need [Orcania](https://github.com/babelouest/orcania) and [Yder](https://github.com/babelouest/yder). Those libraries are included in the package `rhonabwy-dev-full_{x.x.x}_{OS}_{ARCH}.tar.gz` in the [Latest release](https://github.com/babelouest/rhonabwy/releases/latest) page. If you're building with CMake, they will be automatically downloaded and installed if missing. ## Pre-compiled packages You can install Rhonabwy with a pre-compiled package available in the [release pages](https://github.com/babelouest/rhonabwy/releases/latest/). ### rhonabwy-dev-full packages The `rhonabwy-dev-full` contain 4 different packages: - liborcania-dev_x.x.x_.ext - libyder-dev_y.y.y_.ext - libulfius-dev_z.z.z_.ext - librhonabwy-dev_a.a.a_.ext You only need to install `liborcania-dev_*`, `libyder-dev_*` for `librhonabwy-dev_*` to work. `libulfius-dev_*` isn't required unless you want to run the test suite. ## Manual install ### CMake - Multi architecture [CMake](https://cmake.org/download/) minimum 3.5 is required. Last Rhonabwy release: [https://github.com/babelouest/rhonabwy/releases/latest/](https://github.com/babelouest/rhonabwy/releases/latest/) Run the CMake script in a sub-directory, example: ```shell $ cd $ mkdir build $ cd build $ cmake .. $ make && sudo make install ``` The available options for CMake are: - `-DWITH_JOURNALD=[on|off]` (default `on`): Build with journald (SystemD) support - `-BUILD_RHONABWY_TESTING=[on|off]` (default `off`): Build unit tests - `-DINSTALL_HEADER=[on|off]` (default `on`): Install header file `rhonabwy.h` - `-DBUILD_RPM=[on|off]` (default `off`): Build RPM package when running `make package` - `-DCMAKE_BUILD_TYPE=[Debug|Release]` (default `Release`): Compile with debugging symbols or not - `-DBUILD_STATIC=[on|off]` (default `off`): Compile static library - `-DBUILD_RHONABWY_DOCUMENTATION=[on|off]` (default `off`): Build documentation with doxygen - `-DWITH_CURL=[on|off]` (default `on`): Use libcurl to download remote content ### Good ol' Makefile Download Rhonabwy from GitHub repository, compile and install. Last Rhonabwy release: [https://github.com/babelouest/rhonabwy/releases/latest/](https://github.com/babelouest/rhonabwy/releases/latest/) ```shell $ cd rhonabwy/src $ make $ sudo make install ``` To disable curl library on build (to avoid its dependencies), you can pass the option `DISABLE_CURL=1` to the make command. ```shell $ cd rhonabwy/src $ make DISABLE_CURL=1 $ sudo make install ``` By default, the shared library and the header file will be installed in the `/usr/local` location. To change this setting, you can modify the `DESTDIR` value in the `src/Makefile`. Example: install Rhonabwy in /tmp/lib directory ```shell $ cd src $ make && make DESTDIR=/tmp install ``` You can install Rhonabwy without root permission if your user has write access to `$(DESTDIR)`. A `ldconfig` command is executed at the end of the install, it will probably fail if you don't have root permission, but this is harmless. If you choose to install Rhonabwy in another directory, you must set your environment variable `LD_LIBRARY_PATH` properly. rhonabwy-1.1.13/_config.yml000066400000000000000000000000311452472117100155530ustar00rootroot00000000000000theme: jekyll-theme-slaterhonabwy-1.1.13/cmake-modules/000077500000000000000000000000001452472117100161605ustar00rootroot00000000000000rhonabwy-1.1.13/cmake-modules/CMakeUninstall.cmake.in000066400000000000000000000020641452472117100224430ustar00rootroot00000000000000if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt") endif (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach (file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program( "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if (NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif (NOT "${rm_retval}" STREQUAL 0) else (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif (IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach (file) rhonabwy-1.1.13/cmake-modules/CTestCustom.cmake.in000066400000000000000000000001421452472117100220010ustar00rootroot00000000000000string(REPLACE ";" " " TESTS "@TESTS@") set(CTEST_CUSTOM_PRE_TEST "@CMAKE_MAKE_PROGRAM@ ${TESTS}")rhonabwy-1.1.13/cmake-modules/FindCheck.cmake000066400000000000000000000054641452472117100210110ustar00rootroot00000000000000#.rst: # FindCheck # ----------- # # Find Check # # Find Check headers and libraries. # # :: # # CHECK_FOUND - True if Check found. # CHECK_INCLUDE_DIRS - Where to find check.h. # CHECK_LIBRARIES - List of libraries when using Check. # CHECK_VERSION_STRING - The version of Check found. #============================================================================= # Copyright 2018 Silvio Clecio # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= # Sat Jan 20 23:33:47 -03 2018 find_package(PkgConfig QUIET) pkg_check_modules(PC_CHECK QUIET check) find_path(CHECK_INCLUDE_DIR NAMES check.h HINTS ${PC_CHECK_INCLUDEDIR} ${PC_CHECK_INCLUDE_DIRS}) find_library(CHECK_LIBRARY NAMES check libcheck HINTS ${PC_CHECK_LIBDIR} ${PC_CHECK_LIBRARY_DIRS}) if (PC_CHECK_VERSION) set(CHECK_VERSION_STRING ${PC_CHECK_VERSION}) elseif (CHECK_INCLUDE_DIR AND EXISTS "${CHECK_INCLUDE_DIR}/check.h") set(check_version_list MAJOR MINOR MICRO) foreach (v ${check_version_list}) set(regex_check_version "^#define CHECK_${v}_VERSION +\\(?([0-9]+)\\)?$") file(STRINGS "${CHECK_INCLUDE_DIR}/check.h" check_version_${v} REGEX "${regex_check_version}") string(REGEX REPLACE "${regex_check_version}" "\\1" check_version_${v} "${check_version_${v}}") unset(regex_check_version) endforeach () set(CHECK_VERSION_STRING "${check_version_MAJOR}.${check_version_MINOR}.${check_version_MICRO}") foreach (v check_version_list) unset(check_version_${v}) endforeach () unset(check_version_list) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Check REQUIRED_VARS CHECK_LIBRARY CHECK_INCLUDE_DIR VERSION_VAR CHECK_VERSION_STRING) if (CHECK_FOUND) set(CHECK_LIBRARIES ${CHECK_LIBRARY}) set(CHECK_INCLUDE_DIRS ${CHECK_INCLUDE_DIR}) if (NOT TARGET Check::Check) add_library(Check::Check UNKNOWN IMPORTED) set_target_properties(Check::Check PROPERTIES IMPORTED_LOCATION "${CHECK_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${CHECK_INCLUDE_DIR}") endif () endif () mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARY) rhonabwy-1.1.13/cmake-modules/FindGnuTLS.cmake000066400000000000000000000051741452472117100211060ustar00rootroot00000000000000#.rst: # FindGnuTLS # ----------- # # Find GnuTLS # # Find Yder headers and libraries. # # :: # # GNUTLS_FOUND - True if GnuTLS found. # GNUTLS_INCLUDE_DIRS - Where to find gnutls/gnutls.h. # GNUTLS_LIBRARIES - List of libraries when using GnuTLS. # GNUTLS_VERSION_STRING - The version of GnuTLS found. #============================================================================= # Copyright 2022 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= find_package(PkgConfig QUIET) pkg_check_modules(PC_GNUTLS QUIET gnutls) find_path(GNUTLS_INCLUDE_DIR NAMES gnutls/gnutls.h HINTS ${PC_GNUTLS_INCLUDEDIR} ${PC_GNUTLS_INCLUDE_DIRS}) find_library(GNUTLS_LIBRARY NAMES gnutls libgnutls HINTS ${PC_GNUTLS_LIBDIR} ${PC_GNUTLS_LIBRARY_DIRS}) set(GNUTLS_VERSION_STRING 0.0.0) if (PC_GNUTLS_VERSION) set(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION}) elseif (GNUTLS_INCLUDE_DIR AND EXISTS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h") set(regex_gnutls_version "^#define[ \t]+GNUTLS_VERSION[ \t]+([^\"]+).*") file(STRINGS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" gnutls_version REGEX "${regex_gnutls_version}") string(REGEX REPLACE "${regex_gnutls_version}" "\\1" GNUTLS_VERSION_STRING "${gnutls_version}") unset(regex_gnutls_version) unset(gnutls_version) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GnuTLS REQUIRED_VARS GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR VERSION_VAR GNUTLS_VERSION_STRING) if (PC_GNUTLS_FOUND) set(GNUTLS_FOUND 1) endif () if (GNUTLS_FOUND) set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY}) set(GNUTLS_INCLUDE_DIRS ${GNUTLS_INCLUDE_DIR}) if (NOT TARGET GnuTLS::GnuTLS) add_library(GnuTLS::GnuTLS UNKNOWN IMPORTED) set_target_properties(GnuTLS::GnuTLS PROPERTIES IMPORTED_LOCATION "${GNUTLS_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${GNUTLS_INCLUDE_DIR}") endif () endif () mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) rhonabwy-1.1.13/cmake-modules/FindJansson.cmake000066400000000000000000000051521452472117100214010ustar00rootroot00000000000000#.rst: # FindJansson # ----------- # # Find Jansson # # Find Jansson headers and libraries. # # :: # # JANSSON_FOUND - True if Jansson found. # JANSSON_INCLUDE_DIRS - Where to find jansson.h. # JANSSON_LIBRARIES - List of libraries when using Jansson. # JANSSON_VERSION_STRING - The version of Jansson found. #============================================================================= # Copyright 2018 Silvio Clecio # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= # Sat Jan 20 12:32:26 -03 2018 find_package(PkgConfig QUIET) pkg_check_modules(PC_JANSSON QUIET jansson) find_path(JANSSON_INCLUDE_DIR NAMES jansson.h HINTS ${PC_JANSSON_INCLUDEDIR} ${PC_JANSSON_INCLUDE_DIRS}) find_library(JANSSON_LIBRARY NAMES jansson libjansson HINTS ${PC_JANSSON_LIBDIR} ${PC_JANSSON_LIBRARY_DIRS}) if (PC_JANSSON_VERSION) set(JANSSON_VERSION_STRING ${PC_JANSSON_VERSION}) elseif (JANSSON_INCLUDE_DIR AND EXISTS "${JANSSON_INCLUDE_DIR}/jansson.h") set(regex_jansson_version "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*") file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h" jansson_version REGEX "${regex_jansson_version}") string(REGEX REPLACE "${regex_jansson_version}" "\\1" JANSSON_VERSION_STRING "${jansson_version}") unset(regex_jansson_version) unset(jansson_version) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Jansson REQUIRED_VARS JANSSON_LIBRARY JANSSON_INCLUDE_DIR VERSION_VAR JANSSON_VERSION_STRING) if (JANSSON_FOUND) set(JANSSON_LIBRARIES ${JANSSON_LIBRARY}) set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR}) if (NOT TARGET Jansson::Jansson) add_library(Jansson::Jansson UNKNOWN IMPORTED) set_target_properties(Jansson::Jansson PROPERTIES IMPORTED_LOCATION "${JANSSON_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${JANSSON_INCLUDE_DIR}") endif () endif () mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY) rhonabwy-1.1.13/cmake-modules/FindMHD.cmake000066400000000000000000000060131452472117100203730ustar00rootroot00000000000000#.rst: # FindMHD # ----------- # # Find libmicrohttpd # # Find libmicrohttpd headers and libraries. # # :: # # MHD_FOUND - True if libmicrohttpd found. # MHD_INCLUDE_DIRS - Where to find microhttpd.h. # MHD_LIBRARIES - List of libraries when using libmicrohttpd. # MHD_VERSION_STRING - The version of libmicrohttpd found. #============================================================================= # Copyright 2018 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= find_package(PkgConfig QUIET) pkg_check_modules(PC_MHD QUIET libmicrohttpd) find_path(MHD_INCLUDE_DIR NAMES microhttpd.h HINTS ${PC_MHD_INCLUDEDIR} ${PC_MHD_INCLUDE_DIRS}) find_library(MHD_LIBRARY NAMES libmicrohttpd microhttpd HINTS ${PC_MHD_LIBDIR} ${PC_MHD_LIBRARY_DIRS}) if (PC_MHD_VERSION) set(MHD_VERSION_STRING ${PC_MHD_VERSION}) elseif (MHD_INCLUDE_DIR AND EXISTS "${MHD_INCLUDE_DIR}/microhttpd.h") set(regex_mhd_version "^#define[ \t]+MHD_VERSION[ \t]+([^\"]+).*") file(STRINGS "${MHD_INCLUDE_DIR}/microhttpd.h" mhd_version REGEX "${regex_mhd_version}") string(REGEX REPLACE "${regex_mhd_version}" "\\1" MHD_VERSION_NUM "${mhd_version}") unset(regex_mhd_version) unset(mhd_version) # parse MHD_VERSION from numerical format 0x12345678 to string format "12.34.56.78" so the version value can be compared to the one returned by pkg-config string(SUBSTRING ${MHD_VERSION_NUM} 2 2 MHD_VERSION_STRING_MAJOR) string(SUBSTRING ${MHD_VERSION_NUM} 4 2 MHD_VERSION_STRING_MINOR) string(SUBSTRING ${MHD_VERSION_NUM} 6 2 MHD_VERSION_STRING_REVISION) string(SUBSTRING ${MHD_VERSION_NUM} 8 2 MHD_VERSION_STRING_PATCH) set(MHD_VERSION_STRING "${MHD_VERSION_STRING_MAJOR}.${MHD_VERSION_STRING_MINOR}.${MHD_VERSION_STRING_REVISION}.${MHD_VERSION_STRING_PATCH}") endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MHD REQUIRED_VARS MHD_LIBRARY MHD_INCLUDE_DIR VERSION_VAR MHD_VERSION_STRING) if (MHD_FOUND) set(MHD_LIBRARIES ${MHD_LIBRARY}) set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR}) if (NOT TARGET MHD::MHD) add_library(MHD::MHD UNKNOWN IMPORTED) set_target_properties(MHD::MHD PROPERTIES IMPORTED_LOCATION "${MHD_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${MHD_INCLUDE_DIRS}") endif () endif () mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY) rhonabwy-1.1.13/cmake-modules/FindNettle.cmake000066400000000000000000000037051452472117100212230ustar00rootroot00000000000000#.rst: # FindNettle # ----------- # # Find Nettle # # Find Nettle headers and libraries. # # :: # # NETTLE_FOUND - True if Nettle found. # NETTLE_INCLUDE_DIRS - Where to find nettle.h. # NETTLE_LIBRARIES - List of libraries when using Nettle. #============================================================================= # Copyright 2019 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= find_package(PkgConfig QUIET) pkg_check_modules(PC_NETTLE QUIET nettle) find_path(NETTLE_INCLUDE_DIR NAMES nettle/version.h HINTS ${PC_NETTLE_INCLUDEDIR} ${PC_NETTLE_INCLUDE_DIRS}) find_library(NETTLE_LIBRARY NAMES nettle libnettle HINTS ${PC_NETTLE_LIBDIR} ${PC_NETTLE_LIBRARY_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Nettle REQUIRED_VARS NETTLE_LIBRARY NETTLE_INCLUDE_DIR) if (NETTLE_FOUND) set(NETTLE_LIBRARIES ${NETTLE_LIBRARY}) set(NETTLE_INCLUDE_DIRS ${NETTLE_INCLUDE_DIR}) if (NOT TARGET Nettle::Nettle) add_library(Nettle::Nettle UNKNOWN IMPORTED) set_target_properties(Nettle::Nettle PROPERTIES IMPORTED_LOCATION "${NETTLE_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${NETTLE_INCLUDE_DIR}") endif () endif () mark_as_advanced(NETTLE_INCLUDE_DIR NETTLE_LIBRARY) rhonabwy-1.1.13/cmake-modules/FindSubunit.cmake000066400000000000000000000043051452472117100214160ustar00rootroot00000000000000#.rst: # FindSubunit # ----------- # # Find Subunit # # Find Subunit headers and libraries. # # :: # # SUBUNIT_FOUND - True if Subunit found. # SUBUNIT_INCLUDE_DIRS - Where to find subunit/child.h. # SUBUNIT_LIBRARIES - List of libraries when using Subunit. # SUBUNIT_VERSION_STRING - The version of Subunit found. #============================================================================= # Copyright 2018 Silvio Clecio # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . #============================================================================= # Fri Jan 19 22:27:51 -03 2018 find_package(PkgConfig QUIET) pkg_check_modules(PC_SUBUNIT QUIET libsubunit) set(SUBUNIT_VERSION_STRING "${PC_SUBUNIT_VERSION}") find_path(SUBUNIT_INCLUDE_DIR NAMES child.h HINTS ${PC_SUBUNIT_INCLUDEDIR} ${PC_SUBUNIT_INCLUDE_DIRS} PATH_SUFFIXES subunit) find_library(SUBUNIT_LIBRARY NAMES subunit libsubunit HINTS ${PC_SUBUNIT_LIBDIR} ${PC_SUBUNIT_LIBRARY_DIRS}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Subunit REQUIRED_VARS SUBUNIT_LIBRARY SUBUNIT_INCLUDE_DIR VERSION_VAR SUBUNIT_VERSION_STRING) if (SUBUNIT_FOUND) set(SUBUNIT_LIBRARIES ${SUBUNIT_LIBRARY}) set(SUBUNIT_INCLUDE_DIRS ${SUBUNIT_INCLUDE_DIR}) if (NOT TARGET Subunit::Subunit) add_library(Subunit::Subunit UNKNOWN IMPORTED) set_target_properties(Subunit::Subunit PROPERTIES IMPORTED_LOCATION "${SUBUNIT_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${SUBUNIT_INCLUDE_DIR}") endif () endif () mark_as_advanced(SUBUNIT_INCLUDE_DIR SUBUNIT_LIBRARY) rhonabwy-1.1.13/cmake-modules/RhonabwyConfig.cmake.in000066400000000000000000000016341452472117100225120ustar00rootroot00000000000000@PACKAGE_INIT@ include("${CMAKE_CURRENT_LIST_DIR}/RhonabwyTargets.cmake") set(WITH_CURL @WITH_CURL@) set(CMAKE_CURRENT_LIST_DIR ${_original_cmake_module_path}) include(CMakeFindDependencyMacro) set(_original_cmake_module_path ${CMAKE_MODULE_PATH}) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") find_dependency(Orcania) find_dependency(Yder) find_dependency(Jansson) find_dependency(Nettle) find_dependency(GnuTLS) find_dependency(ZLIB) if(WITH_CURL) find_dependency(CURL) if(CURL_FOUND AND NOT TARGET CURL::libcurl) add_library(CURL::libcurl UNKNOWN IMPORTED) set_target_properties(CURL::libcurl PROPERTIES INTERFACE_LINK_LIBRARIES "${CURL_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") endif() endif() set(CMAKE_MODULE_PATH ${_original_cmake_module_path}) set(RHONABWY_VERSION_STRING "@PROJECT_VERSION@") set(Rhonabwy_FOUND TRUE) rhonabwy-1.1.13/doc/000077500000000000000000000000001452472117100141775ustar00rootroot00000000000000rhonabwy-1.1.13/doc/doxygen.cfg000066400000000000000000000052171452472117100163420ustar00rootroot00000000000000# Doxyfile 1.9.1 PROJECT_NAME = "Rhonabwy" PROJECT_BRIEF = "Javascript Object Signing and Encryption (JOSE) library - JWK, JWKS, JWS, JWE and JWT" INPUT = API.md \ tools/rnbyc/README.md \ ./src/ \ ./include/ USE_MDFILE_AS_MAINPAGE = API.md #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 OUTPUT_DIRECTORY = doc CREATE_SUBDIRS = NO ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the TAB_SIZE = 4 OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO OPTIMIZE_OUTPUT_SLICE = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = NO #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.h \ *.md RECURSIVE = YES #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 HTML_DYNAMIC_MENUS = YES HTML_DYNAMIC_SECTIONS = NO GENERATE_LATEX = NO GENERATE_RTF = NO GENERATE_MAN = NO GENERATE_XML = NO GENERATE_DOCBOOK = NO GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES HAVE_DOT = NO rhonabwy-1.1.13/examples/000077500000000000000000000000001452472117100152505ustar00rootroot00000000000000rhonabwy-1.1.13/examples/.gitignore000066400000000000000000000001171452472117100172370ustar00rootroot00000000000000jwt-sign-rs256 jwt-verify-es256 jwt-encrypt-pbes2-h256 jwt-decrypt-rsa-oaep256 rhonabwy-1.1.13/examples/Makefile000066400000000000000000000014011452472117100167040ustar00rootroot00000000000000# # Rhonabwy library # # Makefile used to build the examples # # License: MIT # RHONABWY_INCLUDE=../include RHONABWY_LOCATION=../src RHONABWY_LIBRARY=$(RHONABWY_LOCATION)/librhonabwy.so CC=gcc CFLAGS+=-Wall -I$(RHONABWY_INCLUDE) -DDEBUG -g -O0 $(CPPFLAGS) LDFLAGS=-lc -L$(RHONABWY_LIBRARY) -lrhonabwy TARGET=jwt-sign-rs256 jwt-verify-es256 jwt-encrypt-pbes2-h256 jwt-decrypt-rsa-oaep256 jwks-parse-extract all: build clean: rm -f $(TARGET) $(RHONABWY_LIBRARY): $(RHONABWY_LOCATION)/misc.c $(RHONABWY_LOCATION)/jwk.c $(RHONABWY_LOCATION)/jwks.c $(RHONABWY_LOCATION)/jws.c $(RHONABWY_LOCATION)/jwe.c $(RHONABWY_LOCATION)/jwt.c $(RHONABWY_INCLUDE)/rhonabwy.h cd $(RHONABWY_LOCATION) && $(MAKE) debug $* %: %.c $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) build: $(TARGET) rhonabwy-1.1.13/examples/README.md000066400000000000000000000011011452472117100165200ustar00rootroot00000000000000# Rhonabwy examples use These sample code show basic use of a JWT: - Serialize a signed JWT - Parse a serialized JWT signed and verify its signature - Serialize an encrypted JWT - Parse a serialized JWT encrypted and decrypt its content Basic use of JWK and JWKS: - Parse keys in different formats - Insert these JWK in a JWKS structure - Get a JWK from the JWKS by its index - Get a JWK from the JWKS by its KID - Get only the RSA keys of a JWKS with a simple search ## Build an example ```C $ make # to build all files $ make jwt-verify-es256 # to build one example ``` rhonabwy-1.1.13/examples/jwks-parse-extract.c000066400000000000000000000143171452472117100211600ustar00rootroot00000000000000/** * * Rhonabwy Javascript Object Signing and Encryption (JOSE) library * * Example program with a JWKS * - Parse keys and insert into a JWKS * - Extract keys using an index or a kid * - Search for a subset of the JWKS containing the RSA keys only * - Get JWKS content from a remote location using an url * * Copyright 2022 Nicolas Mora * * License MIT * * To compile with gcc, use the following command: * gcc -o jwks-parse-extract jwks-parse-extract.c -lrhonabwy * */ #include #include const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n"\ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n"\ "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n"\ "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n"\ "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n"\ "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n"\ "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n"\ "BwIDAQAB\n"\ "-----END PUBLIC KEY-----\n"; const char jwk_key_256_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8\",\"kid\":\"8\"}"; const char password[] = "secret"; const unsigned char symkey[] = {4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206}; const char jwks_uri[] = "https://example.com/jwks"; int main(void) { jwks_t * jwks = NULL, * jwks_sub = NULL; jwk_t * jwk = NULL; char * output = NULL; // Import several keys in jwks if (NULL != (jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, jwk_privkey_rsa_str, R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str, R_IMPORT_PEM, R_X509_TYPE_PUBKEY, rsa_2048_pub, sizeof(rsa_2048_pub), R_IMPORT_JSON_STR, jwk_key_256_1, R_IMPORT_PASSWORD, password, R_IMPORT_SYMKEY, symkey, sizeof(symkey), R_IMPORT_NONE))) { // Display the JWKS content output = r_jwks_export_to_json_str(jwks, 1); printf("##### Imported JWKS #####\n"); printf("JWKS content:\n%s\n\n", output); r_free(output); // Get the second key in the JWKS (index 1 because arrays start at 0!) jwk = r_jwks_get_at(jwks, 1); output = r_jwk_export_to_json_str(jwk, 1); printf("Second JWK content:\n%s\n\n", output); r_free(output); r_jwk_free(jwk); // Get the key with the kid '8' in the JWKS jwk = r_jwks_get_by_kid(jwks, "8"); output = r_jwk_export_to_json_str(jwk, 1); printf("JWK with the kid '8' content:\n%s\n\n", output); r_free(output); r_jwk_free(jwk); // Search for RSA keys jwks_sub = r_jwks_search_json_str(jwks, "{\"kty\":\"RSA\"}"); // Display the result JWKS output = r_jwks_export_to_json_str(jwks_sub, 1); printf("JWKS with RSA keys only content:\n%s\n", output); r_free(output); r_jwks_free(jwks_sub); printf("##### Imported JWKS #####\n\n"); r_jwks_free(jwks); } // Get jwks content from remote url if (NULL != (jwks = r_jwks_quick_import(R_IMPORT_JKU, jwks_uri, 0, R_IMPORT_NONE))) { // Display the JWKS content output = r_jwks_export_to_json_str(jwks, 1); printf("##### Remote JWKS #####\n"); printf("JWKS content:\n%s\n", output); r_free(output); r_jwks_free(jwks); printf("##### Remote JWKS #####\n"); } return 0; } rhonabwy-1.1.13/examples/jwt-decrypt-rsa-oaep256.c000066400000000000000000000113361452472117100216360ustar00rootroot00000000000000/** * * Rhonabwy Javascript Object Signing and Encryption (JOSE) library * * Example program with a encrypted token using RSA-OAEP-256 * * Copyright 2022 Nicolas Mora * * License MIT * * To compile with gcc, use the following command: * gcc -o jwt-decrypt-rsa-oaep256 jwt-decrypt-rsa-oaep256.c -lrhonabwy * */ #include #include const char token[] = "eyJ6aXAiOiJERUYiLCJ0eXAiOiJKV1QiLCJhbGciOiJSU0EtT0FFUC0yNTYiLCJraWQiOiIyMDExLTA0LTI5IiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9." // Protected Header "l57396lDUn2epeG4h0DxwzJ0cHooWJcCsBxupsN2Znwj1yzRQZdYrHwxTs9eexsb7YM_cTjFJ-lTm0Cj8PBWWkttlTfy5jjzyfCt-pTqCBReJ5kCxmNN0" // Encrypted Key (1) "9xsABx2-6MdoWSTG8afZoqgdv-shqwLRvx-gAOlFqO-RnleveXcWRxxfxZwp3LeJ3iU7sZjIDjiQ4EbnFkvQ2vBNw2WB5mT7xYWi0mlnKsK9CIRWBWy" // Encrypted Key (2) "aC2yjZnOFZIBthY8dWMI4kKehfIPLNTupiq95hvja_Qq-XmuyVk4V9GFPKNzZgMa2MD_zL1SoSqNBevR4MONHbjjGNu-FZ9azIq040tFqDlO-Q." // Encrypted Key (3) "u8FPu7CC6nJSRLPB0QwXtQ." // Initialization Vector "Zo1ebFtu0Jn0zNTfvouUV3dMs1eNKEddjOrog_zJ5cx0_KyR9nevmIqO2yVC0rZSJW0MO6IpcW3h4gFqt_5iTg." // Ciphertext "2_G4OhGzIl9vcgfcP0Yd6g"; // Authentication Tag const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; int main(void) { jwk_t * jwk = NULL; jwt_t * jwt = NULL; const char * aud, * iss; rhn_int_t iat; // Import RSA private key to decrypt the JWT if (NULL != (jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_privkey_rsa_str))) { // Parse the token into a jwt_t structure if (NULL != (jwt = r_jwt_quick_parse(token, R_PARSE_NONE, 0))) { // Decrypt the token signature with the private key if (r_jwt_decrypt(jwt, jwk, 0) == RHN_OK) { // Get token claims to use them in your program aud = r_jwt_get_claim_str_value(jwt, "aud"); iss = r_jwt_get_claim_str_value(jwt, "iss"); iat = r_jwt_get_claim_int_value(jwt, "iat"); printf("Token decrypted.\n\n"); printf("Payload claims\n- aud: %s\n- iss: %s\n- iat %"RHONABWY_INTEGER_FORMAT"\n", aud, iss, iat); } else { printf("Token not decrypted!\n"); } } // else handle r_jwt_quick_parse error } // else handle r_jwk_quick_import error // Deallocate the jwt and the jwk used r_jwk_free(jwk); r_jwt_free(jwt); return 0; } rhonabwy-1.1.13/examples/jwt-encrypt-pbes2-h256.c000066400000000000000000000040371452472117100214010ustar00rootroot00000000000000/** * * Rhonabwy Javascript Object Signing and Encryption (JOSE) library * * Example program with a encrypted token using PBES2-H256 * * Copyright 2022 Nicolas Mora * * License MIT * * To compile with gcc, use the following command: * gcc -o jwt-encrypt-pbes2-h256 jwt-encrypt-pbes2-h256.c -lrhonabwy * */ #include #include const char password[] = "secret"; int main(void) { jwk_t * jwk = NULL; jwt_t * jwt = NULL; char * token = NULL; // Import password to encrypt the AES key used to encrypt the payload if (NULL != (jwk = r_jwk_quick_import(R_IMPORT_PASSWORD, password))) { // Initialize the jwt_t structure if (RHN_OK == r_jwt_init(&jwt)) { // Initialize jwt's content // The payload will have the following content {"aud": "abcd1234", "iat": 1466571360, "iss": "https://example.com"} // The header will have the following content {"alg": "PBES2-HS256+A128KW", "enc": "A128CBC-HS256", "p2c": 4096, "p2s": "xxxxxxxxxxx", "typ": "JWT", "zip": "DEF"} // The "zip": "DEF" header specifies that the payload is compressed before encryption if (RHN_OK == r_jwt_set_properties(jwt, RHN_OPT_ENC_ALG, R_JWA_ALG_PBES2_H256, RHN_OPT_ENC, R_JWA_ENC_A128CBC, RHN_OPT_HEADER_STR_VALUE, "zip", "DEF", RHN_OPT_CLAIM_STR_VALUE, "iss", "https://example.com", RHN_OPT_CLAIM_STR_VALUE, "aud", "abcd1234", RHN_OPT_CLAIM_INT_VALUE, "iat", 1466571360, RHN_OPT_NONE)) { token = r_jwt_serialize_encrypted(jwt, jwk, 0); printf("token: %s\n", token); r_free(token); } // else handle r_jwt_set_properties error } // else handle r_jwt_init error } // else handle r_jwk_quick_import error // Deallocate the jwt and the jwk used r_jwk_free(jwk); r_jwt_free(jwt); return 0; } rhonabwy-1.1.13/examples/jwt-sign-rs256.c000066400000000000000000000076041452472117100200440ustar00rootroot00000000000000/** * * Rhonabwy Javascript Object Signing and Encryption (JOSE) library * * Example program with a signed JWT using RS256 * * Copyright 2022 Nicolas Mora * * License MIT * * To compile with gcc, use the following command: * gcc -o jwt-sign-rs256 jwt-sign-rs256.c -lrhonabwy * */ #include #include const char sign_key[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; int main(void) { jwk_t * jwk = NULL; jwt_t * jwt = NULL; char * token = NULL; // Imports RSA private key to sign the token if (NULL != (jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, sign_key))) { // Initialize the jwt_t structure if (RHN_OK == r_jwt_init(&jwt)) { // Initialize jwt's content // The payload will have the following content {"aud": "abcd1234", "iat": 1466571360, "iss": "https://example.com"} // The header will have the following content {"alg": "RS256", "kid": "2011-04-29", "str": "a value", "typ": "JWT"} if (RHN_OK == r_jwt_set_properties(jwt, RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_HEADER_STR_VALUE, "str", "a value", RHN_OPT_CLAIM_STR_VALUE, "iss", "https://example.com", RHN_OPT_CLAIM_STR_VALUE, "aud", "abcd1234", RHN_OPT_CLAIM_INT_VALUE, "iat", 1466571360, RHN_OPT_NONE)) { // Serialize the JWT using the RSA provate key to sign the token token = r_jwt_serialize_signed(jwt, jwk, 0); printf("Token: %s\n", token); // Deallocate the seralized token r_free(token); } // else handle r_jwt_set_properties error } // else handle r_jwt_init error } // else handle r_jwk_quick_import error // Deallocate the jwt and the jwk used r_jwk_free(jwk); r_jwt_free(jwt); return 0; } rhonabwy-1.1.13/examples/jwt-verify-es256.c000066400000000000000000000041241452472117100203650ustar00rootroot00000000000000/** * * Rhonabwy Javascript Object Signing and Encryption (JOSE) library * * Example program with a signed token using ES256 verified with the corresponding public key * * Copyright 2022 Nicolas Mora * * License MIT * * To compile with gcc, use the following command: * gcc -o jwt-verify-es256 jwt-verify-es256.c -lrhonabwy * */ #include #include const char token[] = "eyJzdHIiOiJhIHZhbHVlIiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYiLCJraWQiOiIxIn0." // header "eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwiYXVkIjoiYWJjZDEyMzQiLCJpYXQiOjE0NjY1NzEzNjB9." // payload "NFG06xZA7rscnn5nrW9X2Yd00wgXkmMUjo1JAYUmrKH0ez09x8NDP4z03DV1X-0lYCcFNZ_Fu7dyb9hSYGXE7g"; // signature const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"kid\":\"1\",\"alg\":\"ES256\"}"; int main(void) { jwk_t * jwk = NULL; jwt_t * jwt = NULL; const char * aud, * iss; rhn_int_t iat; // Imports EC public key to verify the token signature if (NULL != (jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str))) { // Parse the token into a jwt_t structure if (NULL != (jwt = r_jwt_quick_parse(token, R_PARSE_NONE, 0))) { // Verify the token signature with the public key if (r_jwt_verify_signature(jwt, jwk, 0) == RHN_OK) { // Get token claims to use them in your program aud = r_jwt_get_claim_str_value(jwt, "aud"); iss = r_jwt_get_claim_str_value(jwt, "iss"); iat = r_jwt_get_claim_int_value(jwt, "iat"); printf("Token signature verified.\n\n"); printf("Payload claims\n- aud: %s\n- iss: %s\n- iat %"RHONABWY_INTEGER_FORMAT"\n", aud, iss, iat); } else { printf("Token signature invalid!\n"); } } // else handle r_jwt_quick_parse error } // else handle r_jwk_quick_import error // Deallocate the jwt and the jwk used r_jwk_free(jwk); r_jwt_free(jwt); return 0; } rhonabwy-1.1.13/include/000077500000000000000000000000001452472117100150555ustar00rootroot00000000000000rhonabwy-1.1.13/include/rhonabwy-cfg.h.in000066400000000000000000000032651452472117100202270ustar00rootroot00000000000000/** * * Rhonabwy JSON Web Key (JWK) library * * rhonabwy-cfg.h: configuration file * * Copyright 2020-2022 Nicolas Mora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #ifndef _RHONABWY_CFG_H_ #define _RHONABWY_CFG_H_ #define RHONABWY_VERSION ${PROJECT_VERSION} #define RHONABWY_VERSION_STR "${PROJECT_VERSION}" #define RHONABWY_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} #define RHONABWY_VERSION_MINOR ${PROJECT_VERSION_MINOR} #define RHONABWY_VERSION_PATCH ${PROJECT_VERSION_PATCH} #define RHONABWY_VERSION_NUMBER ((RHONABWY_VERSION_MAJOR << 16) | (RHONABWY_VERSION_MINOR << 8) | (RHONABWY_VERSION_PATCH << 0)) #define RHONABWY_CHECK_VERSION(major,minor,patch) \ (RHONABWY_VERSION_MAJOR > (major) || \ (RHONABWY_VERSION_MAJOR == (major) && RHONABWY_VERSION_MINOR > (minor)) || \ (RHONABWY_VERSION_MAJOR == (major) && RHONABWY_VERSION_MINOR == (minor) && \ RHONABWY_VERSION_PATCH >= (patch))) #define NETTLE_VERSION_NUMBER ((NETTLE_VERSION_MAJOR << 16) | (NETTLE_VERSION_MINOR << 8)) #cmakedefine R_WITH_CURL #endif /* _RHONABWY_CFG_H_ */ rhonabwy-1.1.13/include/rhonabwy.h000066400000000000000000004254051452472117100170710ustar00rootroot00000000000000/** * * @file rhonabwy.h * @brief Rhonabwy JSON Web Key (JWK) library * * rhonabwy.h: structures and functions declarations * * Copyright 2020-2022 Nicolas Mora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #ifndef __RHONABWY_H_ #define __RHONABWY_H_ #ifdef __cplusplus extern "C" { #endif #include "rhonabwy-cfg.h" #include #include #include #include /** * @defgroup const Constants and properties * Constant values used as input or output * @{ */ #define RHN_OK 0 #define RHN_ERROR 1 #define RHN_ERROR_MEMORY 2 #define RHN_ERROR_PARAM 3 #define RHN_ERROR_UNSUPPORTED 4 #define RHN_ERROR_INVALID 5 #define R_X509_TYPE_UNSPECIFIED 0 #define R_X509_TYPE_PUBKEY 1 #define R_X509_TYPE_PRIVKEY 2 #define R_X509_TYPE_CERTIFICATE 3 #define R_FORMAT_PEM 0 #define R_FORMAT_DER 1 #define R_KEY_TYPE_NONE 0x00000000 #define R_KEY_TYPE_PUBLIC 0x00000001 #define R_KEY_TYPE_PRIVATE 0x00000010 #define R_KEY_TYPE_SYMMETRIC 0x00000100 #define R_KEY_TYPE_RSA 0x00001000 #define R_KEY_TYPE_EC 0x00010000 #define R_KEY_TYPE_HMAC 0x00100000 #define R_KEY_TYPE_EDDSA 0x01000000 #define R_KEY_TYPE_ECDH 0x10000000 #define R_FLAG_IGNORE_SERVER_CERTIFICATE 0x00000001 #define R_FLAG_FOLLOW_REDIRECT 0x00000010 #define R_FLAG_IGNORE_REMOTE 0x00000100 #define R_JWT_TYPE_NONE 0 #define R_JWT_TYPE_SIGN 1 #define R_JWT_TYPE_ENCRYPT 2 #define R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT 3 #define R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN 4 #define R_JWT_CLAIM_NOW -1 #define R_JWT_CLAIM_PRESENT -2 #define R_JWK_THUMB_SHA256 0 #define R_JWK_THUMB_SHA384 1 #define R_JWK_THUMB_SHA512 2 #define R_JSON_MODE_COMPACT 0 #define R_JSON_MODE_GENERAL 1 #define R_JSON_MODE_FLATTENED 2 #define R_PARSE_NONE 0 #define R_PARSE_HEADER_JWK 1 #define R_PARSE_HEADER_JKU 2 #define R_PARSE_HEADER_X5C 4 #define R_PARSE_HEADER_X5U 8 #define R_PARSE_HEADER_ALL (R_PARSE_HEADER_JWK|R_PARSE_HEADER_JKU|R_PARSE_HEADER_X5C|R_PARSE_HEADER_X5U) #define R_PARSE_UNSIGNED 16 #define R_PARSE_ALL (R_PARSE_HEADER_ALL|R_PARSE_UNSIGNED) #define R_MAX_BODY_SIZE 4194304 /** * @} */ /** * @defgroup type JWK, JWKS, JWS, JWE type * Definition of the types jwk_t, jwks_t, jws_t and jwe_t * @{ */ typedef json_t jwk_t; typedef json_t jwks_t; typedef json_int_t rhn_int_t; #define RHONABWY_INTEGER_FORMAT JSON_INTEGER_FORMAT typedef enum { R_JWA_ALG_UNKNOWN = 0, R_JWA_ALG_NONE = 1, R_JWA_ALG_HS256 = 2, R_JWA_ALG_HS384 = 3, R_JWA_ALG_HS512 = 4, R_JWA_ALG_RS256 = 5, R_JWA_ALG_RS384 = 6, R_JWA_ALG_RS512 = 7, R_JWA_ALG_ES256 = 8, R_JWA_ALG_ES384 = 9, R_JWA_ALG_ES512 = 10, R_JWA_ALG_EDDSA = 11, R_JWA_ALG_PS256 = 12, R_JWA_ALG_PS384 = 13, R_JWA_ALG_PS512 = 14, R_JWA_ALG_RSA1_5 = 15, R_JWA_ALG_RSA_OAEP = 16, R_JWA_ALG_RSA_OAEP_256 = 17, R_JWA_ALG_A128KW = 18, R_JWA_ALG_A192KW = 19, R_JWA_ALG_A256KW = 20, R_JWA_ALG_DIR = 21, R_JWA_ALG_ECDH_ES = 22, R_JWA_ALG_ECDH_ES_A128KW = 23, R_JWA_ALG_ECDH_ES_A192KW = 24, R_JWA_ALG_ECDH_ES_A256KW = 25, R_JWA_ALG_A128GCMKW = 26, R_JWA_ALG_A192GCMKW = 27, R_JWA_ALG_A256GCMKW = 28, R_JWA_ALG_PBES2_H256 = 29, R_JWA_ALG_PBES2_H384 = 30, R_JWA_ALG_PBES2_H512 = 31, R_JWA_ALG_ES256K = 32 } jwa_alg; typedef enum { R_JWT_CLAIM_NOP = 0, R_JWT_CLAIM_ISS = 1, R_JWT_CLAIM_SUB = 2, R_JWT_CLAIM_AUD = 3, R_JWT_CLAIM_EXP = 4, R_JWT_CLAIM_NBF = 5, R_JWT_CLAIM_IAT = 6, R_JWT_CLAIM_JTI = 7, R_JWT_CLAIM_STR = 8, R_JWT_CLAIM_INT = 9, R_JWT_CLAIM_JSN = 10, R_JWT_CLAIM_TYP = 11, R_JWT_CLAIM_CTY = 12, R_JWT_CLAIM_AMR = 13, } rhn_claim_opt; typedef enum { R_JWA_ENC_UNKNOWN = 0, R_JWA_ENC_A128CBC = 1, R_JWA_ENC_A192CBC = 2, R_JWA_ENC_A256CBC = 3, R_JWA_ENC_A128GCM = 4, R_JWA_ENC_A192GCM = 5, R_JWA_ENC_A256GCM = 6 } jwa_enc; typedef enum { RHN_OPT_NONE = 0, ///< End option list, mandatory at the end of the option list RHN_OPT_HEADER_INT_VALUE = 1, ///< Header Integer value, following parameters must be const char * name, int i_value RHN_OPT_HEADER_RHN_INT_VALUE = 2, ///< Header rhn_int_t value, following parameters must be const char * name, rhn_int_t i_value RHN_OPT_HEADER_STR_VALUE = 3, ///< Header String value, following parameters must be const char * name, const char * str_value RHN_OPT_HEADER_JSON_T_VALUE = 4, ///< Header JSON value, following parameters must be const char * name, json_t * j_value RHN_OPT_HEADER_FULL_JSON_T = 5, ///< JSON value to set the entire header, following parameter must be json_t * j_value RHN_OPT_HEADER_FULL_JSON_STR = 6, ///< Stringified JSON value to set the entire header, following parameter must be const char * str_value RHN_OPT_UN_HEADER_FULL_JSON_T = 7, ///< JSON value to set the entire unprotected header, following parameter must be json_t * j_value RHN_OPT_UN_HEADER_FULL_JSON_STR = 8, ///< Stringified JSON value to set the entire unprotected header, following parameter must be const char * str_value RHN_OPT_PAYLOAD = 9, ///< JSON value to set the entire payload, following parameters must be const unsigned char * value, size_t value_length RHN_OPT_CLAIM_INT_VALUE = 10, ///< Claims Integer value, following parameters must be const char * name, int i_value RHN_OPT_CLAIM_RHN_INT_VALUE = 11, ///< Claims Integer value, following parameters must be const char * name, int i_value RHN_OPT_CLAIM_STR_VALUE = 12, ///< Claims String value, following parameters must be const char * name, const char * str_value RHN_OPT_CLAIM_JSON_T_VALUE = 13, ///< Claims JSON value, following parameters must be const char * name, json_t * j_value RHN_OPT_CLAIM_FULL_JSON_T = 14, ///< JSON value to set the entire claims, following parameter must be json_t * j_value RHN_OPT_CLAIM_FULL_JSON_STR = 15, ///< Stringified JSON value to set the entire claims, following parameter must be const char * str_value RHN_OPT_ENC_ALG = 16, ///< Key management algorithm, following parameter must be a jwa_alg value RHN_OPT_ENC = 17, ///< Encryption algorithm, following parameter must be a jwa_enc value RHN_OPT_SIG_ALG = 18, ///< Signature algorithm, following parameter must be a jwa_alg value RHN_OPT_CIPHER_KEY = 19, ///< Cipher key to encrypt data, following parameters must be const unsigned char * value, size_t value_length RHN_OPT_IV = 20, ///< Initial Value (IV) for data encryption, following parameters must be const unsigned char * value, size_t value_length RHN_OPT_AAD = 21, ///< Additional Authenticated Data (AAD) for data encryption, following parameters must be const unsigned char * value, size_t value_length RHN_OPT_SIGN_KEY_JWK = 22, ///< Private key in JWK format to sign the token, following parameter must be a jwk_t * value RHN_OPT_SIGN_KEY_JWKS = 23, ///< Private key set in JWKS format to sign the token, following parameter must be a jwks_t * value RHN_OPT_SIGN_KEY_GNUTLS = 24, ///< Private key in GnuTLS format to sign the token, following parameter must be a gnutls_privkey_t value RHN_OPT_SIGN_KEY_JSON_T = 25, ///< Private key in JSON format to sign the token, following parameter must be a json_t * value RHN_OPT_SIGN_KEY_JSON_STR = 26, ///< Private key in stringified JSON format to sign the token, following parameter must be a const char * value RHN_OPT_SIGN_KEY_PEM_DER = 27, ///< Private key in PEM or DER format to sign the token, following parameter must be R_FORMAT_PEM or R_FORMAT_DER, const unsigned char * value, size_t value_length RHN_OPT_VERIFY_KEY_JWK = 28, ///< Public key in JWK format to verify the token signature, following parameter must be a jwk_t * value RHN_OPT_VERIFY_KEY_JWKS = 29, ///< Public key set in JWKS format to verify the token signature, following parameter must be a jwks_t * value RHN_OPT_VERIFY_KEY_GNUTLS = 30, ///< Public key in GnuTLS format to verify the token signature, following parameter must be a gnutls_pubkey_t value RHN_OPT_VERIFY_KEY_JSON_T = 31, ///< Public key in JSON format to verify the token signature, following parameter must be a json_t * value RHN_OPT_VERIFY_KEY_JSON_STR = 32, ///< Public key in stringified JSON format to verify the token signature, following parameter must be a const char * value RHN_OPT_VERIFY_KEY_PEM_DER = 33, ///< Public key in PEM or DER format to verify the token signature, following parameter must be R_FORMAT_PEM or R_FORMAT_DER, const unsigned char * value, size_t value_length RHN_OPT_ENCRYPT_KEY_JWK = 34, ///< Public key in JWK format to encrypt the token, following parameter must be a jwk_t * value RHN_OPT_ENCRYPT_KEY_JWKS = 35, ///< Public key set in JWKS format to encrypt the token, following parameter must be a jwks_t * value RHN_OPT_ENCRYPT_KEY_GNUTLS = 36, ///< Public key in GnuTLS format to encrypt the token, following parameter must be a gnutls_pubkey_t value RHN_OPT_ENCRYPT_KEY_JSON_T = 37, ///< Public key in JSON format to encrypt the token, following parameter must be a json_t * value RHN_OPT_ENCRYPT_KEY_JSON_STR = 38, ///< Public key in stringified JSON format to encrypt the token, following parameter must be a const char * value RHN_OPT_ENCRYPT_KEY_PEM_DER = 39, ///< Public key in PEM or DER format to encrypt the token, following parameter must be R_FORMAT_PEM or R_FORMAT_DER, const unsigned char * value, size_t value_length RHN_OPT_DECRYPT_KEY_JWK = 40, ///< Private key in JWK format to decrypt the token, following parameter must be a jwk_t * value RHN_OPT_DECRYPT_KEY_JWKS = 41, ///< Private key set in JWKS format to decrypt the token, following parameter must be a jwks_t * value RHN_OPT_DECRYPT_KEY_GNUTLS = 42, ///< Private key in GnuTLS format to decrypt the token, following parameter must be a gnutls_privkey_t value RHN_OPT_DECRYPT_KEY_JSON_T = 43, ///< Private key in JSON format to decrypt the token, following parameter must be a json_t * value RHN_OPT_DECRYPT_KEY_JSON_STR = 44, ///< Private key in stringified JSON format to decrypt the token, following parameter must be a const char * value RHN_OPT_DECRYPT_KEY_PEM_DER = 45 ///< Private key in PEM or DER format to decrypt the token, following parameter must be R_FORMAT_PEM or R_FORMAT_DER, const unsigned char * value, size_t value_length } rhn_opt; typedef enum { R_IMPORT_NONE = 0, ///< End option list, mandatory at the end of the option list when using r_jwks_quick_import R_IMPORT_JSON_STR = 1, ///< Import from a stringified JSON, following parameter must be a const char * value R_IMPORT_JSON_T = 2, ///< Import from a json_t *, following parameter must be a const json_t * value R_IMPORT_PEM = 3, ///< Import from a X509 key in PEM format, following parameters must be type (R_X509_TYPE_PUBKEY, R_X509_TYPE_PRIVKEY or R_X509_TYPE_CERTIFICATE), const unsigned char *, size_t R_IMPORT_DER = 4, ///< Import from a X509 key in DER format, following parameters must be type (R_X509_TYPE_PUBKEY, R_X509_TYPE_PRIVKEY or R_X509_TYPE_CERTIFICATE), const unsigned char *, size_t R_IMPORT_G_PRIVKEY = 5, ///< Import from a gnutls_privkey_t, following parameters must be gnutls_privkey_t R_IMPORT_G_PUBKEY = 6, ///< Import from a gnutls_pubkey_t, following parameters must be gnutls_pubkey_t R_IMPORT_G_CERT = 7, ///< Import from a gnutls_x509_crt_t, following parameters must be gnutls_x509_crt_t R_IMPORT_X5U = 8, ///< Import from an URL pointing to a x5u, following parameters must be x5u_flags (R_FLAG_IGNORE_SERVER_CERTIFICATE, R_FLAG_FOLLOW_REDIRECT, R_FLAG_IGNORE_REMOTE), const char * value R_IMPORT_SYMKEY = 9, ///< Import from a symmetric key, following parameters must be const unsigned char *, size_t R_IMPORT_PASSWORD = 10, ///< Import from a password, following parameter must be a const char * value R_IMPORT_JKU = 11 ///< Import from an URL pointing to a jku, available for r_jwks_quick_import only, following parameters must be x5u_flags (R_FLAG_IGNORE_SERVER_CERTIFICATE, R_FLAG_FOLLOW_REDIRECT, R_FLAG_IGNORE_REMOTE), const char * value } rhn_import; typedef struct { unsigned char * header_b64url; unsigned char * payload_b64url; unsigned char * signature_b64url; json_t * j_header; jwa_alg alg; jwks_t * jwks_privkey; jwks_t * jwks_pubkey; unsigned char * payload; size_t payload_len; json_t * j_json_serialization; int token_mode; } jws_t; typedef struct { unsigned char * header_b64url; unsigned char * encrypted_key_b64url; unsigned char * aad_b64url; unsigned char * iv_b64url; unsigned char * ciphertext_b64url; unsigned char * auth_tag_b64url; json_t * j_header; json_t * j_unprotected_header; jwa_alg alg; jwa_enc enc; jwks_t * jwks_privkey; jwks_t * jwks_pubkey; unsigned char * aad; size_t aad_len; unsigned char * key; size_t key_len; unsigned char * iv; size_t iv_len; unsigned char * payload; size_t payload_len; json_t * j_json_serialization; int token_mode; } jwe_t; typedef struct { int type; uint32_t parse_flags; json_t * j_header; json_t * j_claims; jws_t * jws; jwe_t * jwe; jwa_alg sign_alg; jwa_alg enc_alg; jwa_enc enc; unsigned char * key; size_t key_len; unsigned char * iv; size_t iv_len; jwks_t * jwks_privkey_sign; jwks_t * jwks_pubkey_sign; jwks_t * jwks_privkey_enc; jwks_t * jwks_pubkey_enc; } jwt_t; /** * @} */ /** * @defgroup core Core functions * Core functions used to initialize or free jwk_t * and check if a jwk is valid and its type * @{ */ /** * Initialize rhonabwy global parameters * This function isn't thread-safe so it must be called once before any other call to rhonabwy functions * The function r_global_close must be called when rhonabwy library is no longer required * @return RHN_OK on success, an error value on error */ int r_global_init(void); /** * Close rhonabwy global parameters */ void r_global_close(void); /** * Get the library information as a json_t * object * - library version * - supported JWS algorithms * - supported JWE algorithms * @return the library information */ json_t * r_library_info_json_t(void); /** * Get the library information as a JSON object in string format * - library version * - supported JWS algorithms * - supported JWE algorithms * @return the library information, must be r_free'd after use */ char * r_library_info_json_str(void); /** * Free a heap allocated variable * previously returned by a rhonabwy function * @param data: the data to free */ void r_free(void * data); /** * Initialize a jwk_t * @param jwk: a reference to a jwk_t * to initialize * @return RHN_OK on success, an error value on error */ int r_jwk_init(jwk_t ** jwk); /** * Free a jwk_t * @param jwk: the jwk_t * to free */ void r_jwk_free(jwk_t * jwk); /** * Initialize a jwks_t * @param jwks: a reference to a jwks_t * to initialize * @return RHN_OK on success, an error value on error */ int r_jwks_init(jwks_t ** jwks); /** * Free a jwks_t * @param jwks: the jwks_t * to free */ void r_jwks_free(jwks_t * jwks); /** * Initialize a jws_t * @param jws: a reference to a jws_t * to initialize * @return RHN_OK on success, an error value on error */ int r_jws_init(jws_t ** jws); /** * Free a jws_t * @param jws: the jws_t * to free */ void r_jws_free(jws_t * jws); /** * Initialize a jwe_t * @param jwe: a reference to a jwe_t * to initialize * @return RHN_OK on success, an error value on error */ int r_jwe_init(jwe_t ** jwe); /** * Free a jwe_t * @param jwe: the jwe_t * to free */ void r_jwe_free(jwe_t * jwe); /** * Initialize a jwt_t * @param jwt: a reference to a jwt_t * to initialize * @return RHN_OK on success, an error value on error */ int r_jwt_init(jwt_t ** jwt); /** * Free a jwt_t * @param jwt: the jwt_t * to free */ void r_jwt_free(jwt_t * jwt); /** * Get the jwa_alg corresponding to the string algorithm specified * @param alg: the algorithm to convert * @return the converted jwa_alg, R_JWA_ALG_NONE if alg is unknown */ jwa_alg r_str_to_jwa_alg(const char * alg); /** * Get the algorithm string * corresponding to the jwa_alg * @param alg: the algorithm to convert * @return its string name */ const char * r_jwa_alg_to_str(jwa_alg alg); /** * Get the jwa_enc corresponding to the string algorithm specified * @param enc: the algorithm to convert * @return the converted jwa_enc, R_JWA_ENC_NONE if enc is unknown */ jwa_enc r_str_to_jwa_enc(const char * enc); /** * Get the encryption string * corresponding to the jwa_enc * @param enc: the encryption to convert * @return its string name */ const char * r_jwa_enc_to_str(jwa_enc enc); /** * @} */ /** * @defgroup jwk_validate Validate a JWK and generate a key pair * @{ */ /** * Get the type and algorithm of a jwk_t * @param jwk: the jwk_t * to test * @param bits: set the key size in bits (may be NULL) * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return an integer containing * - R_KEY_TYPE_NONE if the jwk is invalid * * the type: * - R_KEY_TYPE_PUBLIC: for a public key * - R_KEY_TYPE_PRIVATE: for a private key * - R_KEY_TYPE_SYMMETRIC: for a symmetrick key * * the algorithm used * - R_KEY_TYPE_RSA: for a RSA key * - R_KEY_TYPE_EC: for a EC key * - R_KEY_TYPE_HMAC: for a HMAC key * You must test the result value with bitwise operator * Ex: if (r_jwk_key_type(jwk) & R_KEY_TYPE_PUBLIC) { * if (r_jwk_key_type(jwk) & R_KEY_TYPE_RSA) { * You can combine type and algorithm values in the bitwise operator * Ex: if (r_jwk_key_type(jwk) & (R_KEY_TYPE_RSA|R_KEY_TYPE_PRIVATE)) { */ int r_jwk_key_type(jwk_t * jwk, unsigned int * bits, int x5u_flags); /** * Check if the jwk is valid * @param jwk: the jwk_t * to test * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_is_valid(jwk_t * jwk); /** * Check if the x5u property is valid * @param jwk: the jwk_t * to test * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_is_valid_x5u(jwk_t * jwk, int x5u_flags); /** * Generates a pair of private and public key using given parameters * @param jwk_privkey: the private key to set, must be initialized * @param jwk_pubkey: the public key to set, must be initialized * @param type: the type of key, values available are * R_KEY_TYPE_RSA or R_KEY_TYPE_EC * @param bits: the key size to generate, if the key type is R_KEY_TYPE_EC, * the key size is the curve length: 256, 384 or 512 * @param kid: the key ID to set to the JWKs, if NULL or empty, will be set automatically * @return RHN_OK on success, an error value on error */ int r_jwk_generate_key_pair(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int type, unsigned int bits, const char * kid); /** * @} */ /** * @defgroup jwk_properties JWK Properties * read/write/delete jwk properties * @{ */ /** * Get a property value from a jwk_t * @param jwk: the jwk_t * to get * @param key: the key of the property to retrieve * @return the property value on success, NULL on error */ const char * r_jwk_get_property_str(jwk_t * jwk, const char * key); /** * Get a property value of an array from a jwk_t * @param jwk: the jwk_t * to get * @param key: the key of the property to retrieve * @param index: the index of the value to retrieve in the array * @return the property value on success, NULL on error */ const char * r_jwk_get_property_array(jwk_t * jwk, const char * key, size_t index); /** * Get the array size of a property from a jwt_t * @param jwk: the jwk_t * to get * @param key: the key of the property to retrieve * @return the size of the array, or -1 if the array does not exist */ int r_jwk_get_property_array_size(jwk_t * jwk, const char * key); /** * Set a property value into a jwk_t * @param jwk: the jwk_t * to update * @param key: the key of the property to set * @param value: the value of the property to set * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_set_property_str(jwk_t * jwk, const char * key, const char * value); /** * Set a property value on an array into a jwk_t * @param jwk: the jwk_t * to update * @param key: the key of the property to set * @param index: the index of the value to set in the array * @param value: the value of the property to set * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_set_property_array(jwk_t * jwk, const char * key, size_t index, const char * value); /** * Append a property value on an array into a jwk_t * @param jwk: the jwk_t * to update * @param key: the key of the property to set * @param value: the value of the property to set * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_append_property_array(jwk_t * jwk, const char * key, const char * value); /** * Delete a property from a jwk_t * @param jwk: the jwk_t * to update * @param key: the key of the property to delete * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_delete_property_str(jwk_t * jwk, const char * key); /** * Delete an array property from a jwk_t * @param jwk: the jwk_t * to update * @param key: the key of the property to delete * @param index: the index of the value to set in the array * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_delete_property_array_at(jwk_t * jwk, const char * key, size_t index); /** * Appends a X509 certificate in the x5c array * @param jwk: the jwk_t * to update * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param input: the certificate input, must contain the certificate in PEM or DER format * @param input_len: the length of the data contained in input * @return RHN_OK on success, an error value on error * Logs error message with yder on error */ int r_jwk_append_x5c(jwk_t * jwk, int format, const unsigned char * input, size_t input_len); /** * @} */ /** * @defgroup import JWK Import functions * Import a jwk from JSON data, gnutls inner types or PEM/DER * @{ */ /** * Import a JSON in string format into a jwk_t * @param jwk: the jwk_t * to import to * @param input: a JWK in JSON stringified format * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_json_str(jwk_t * jwk, const char * input); /** * Import a JSON in json_t format into a jwk_t * @param jwk: the jwk_t * to import to * @param j_input: a JWK in json_t * format * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_json_t(jwk_t * jwk, json_t * j_input); /** * Import a public or private key or a X509 certificate in PEM or DER format into a jwk_t * @param jwk: the jwk_t * to import to * @param type: the type of the input, values available are R_X509_TYPE_PUBKEY, R_X509_TYPE_PRIVKEY or R_X509_TYPE_CERTIFICATE * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param input: the input value, must contain the key or the certificate in PEM or DER format * @param input_len: the length of the data contained in input * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_pem_der(jwk_t * jwk, int type, int format, const unsigned char * input, size_t input_len); /** * Import a GnuTLS private key in gnutls_privkey_t format into a jwk_t * @param jwk: the jwk_t * to import to * @param key: the private key to be imported to jwk * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_gnutls_privkey(jwk_t * jwk, gnutls_privkey_t key); /** * Import a GnuTLS public key in gnutls_pubkey_t format into a jwk_t * @param jwk: the jwk_t * to import to * @param pub: the public key to be imported to jwk * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_gnutls_pubkey(jwk_t * jwk, gnutls_pubkey_t pub); /** * Import a GnuTLS X509 certificate in gnutls_x509_crt_t format into a jwk_t * @param jwk: the jwk_t * to import to * @param crt: the X509 certificate whose public key will be imported to jwk * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_gnutls_x509_crt(jwk_t * jwk, gnutls_x509_crt_t crt); /** * Import a certificate from an URL * @param jwk: the jwk_t * to import to * @param x5u_flags: Flags to retrieve x5u certificates * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * @param x5u: the url to retreive the certificate * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_x5u(jwk_t * jwk, int x5u_flags, const char * x5u); /** * Import a key from an x5c value * @param jwk: the jwk_t * to import to * @param x5c: the x5c value * If jwk is set, values will be overwritten * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_x5c(jwk_t * jwk, const char * x5c); /** * Import a symmetric key into a jwk * The key will be converted to base64url format * @param jwk: the jwk_t * to import to * @param key: the key to import * @param key_len: the size of the key * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_symmetric_key(jwk_t * jwk, const unsigned char * key, size_t key_len); /** * Import a password into a jwk * The password will be converted to base64url format * @param jwk: the jwk_t * to import to * @param password: the password to import * @return RHN_OK on success, an error value on error */ int r_jwk_import_from_password(jwk_t * jwk, const char * password); /** * Extract the public key from the private key jwk_privkey and set it into jwk_pubkey * @param jwk_privkey: the jwt containing a private key * @param jwk_pubkey: the jwt that will be set with the public key data * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwk_extract_pubkey(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int x5u_flags); /** * Import data into a jwk * @param type: type of the data to import * Following parameters must be set of values * with the mandatory parameters for each rhn_import * See rhn_import documentation * @return a jwk containing key parsed, or NULL on error */ jwk_t * r_jwk_quick_import(rhn_import type, ...); /** * Return a copy of the JWK * @param jwk: the jwk to copy * @return a copy of the jwk */ jwk_t * r_jwk_copy(jwk_t * jwk); /** * Compare 2 jwk * @param jwk1: the first JWK to compare * @param jwk2: the second JWK to compare * @return 1 if both jwk1 and jwk2 are equal, 0 otherwise */ int r_jwk_equal(jwk_t * jwk1, jwk_t * jwk2); /** * @} */ /** * @defgroup export JWK Export functions * Export a jwk to JSON data, gnutls inner types or PEM/DER * @{ */ /** * Export a jwk_t into a stringified JSON format * @param jwk: the jwk_t * to export * @param pretty: indent or compact JSON output * @return a char * on success, NULL on error, must be r_free'd after use */ char * r_jwk_export_to_json_str(jwk_t * jwk, int pretty); /** * Export a jwk_t into a json_t format * @param jwk: the jwk_t * to export * @return a json_t * on success, NULL on error */ json_t * r_jwk_export_to_json_t(jwk_t * jwk); /** * Export a jwk_t into a gnutls_privkey_t format * @param jwk: the jwk_t * to export * @return a gnutls_privkey_t on success, NULL on error */ gnutls_privkey_t r_jwk_export_to_gnutls_privkey(jwk_t * jwk); /** * Export a jwk_t into a gnutls_pubkey_t format * @param jwk: the jwk_t * to export * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return a gnutls_pubkey_t on success, NULL on error */ gnutls_pubkey_t r_jwk_export_to_gnutls_pubkey(jwk_t * jwk, int x5u_flags); /** * Export a jwk_t into a gnutls_x509_crt_t format * the jwt_t must contain a x5c or a x5u property * pointing to a certificate * @param jwk: the jwk_t * to export * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return a gnutls_x509_crt_t on success, NULL on error */ gnutls_x509_crt_t r_jwk_export_to_gnutls_crt(jwk_t * jwk, int x5u_flags); /** * Export a jwk_t into a DER or PEM format * @param jwk: the jwk_t * to export * @param format: the format of the output, values available are R_FORMAT_PEM or R_FORMAT_DER * @param output: an unsigned char * that will contain the output * @param output_len: the size of output and will be set to the data size that has been written to output * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error * @return RHN_ERROR_PARAM if output_len isn't large enough to hold the output, then output_len will be set to the required size */ int r_jwk_export_to_pem_der(jwk_t * jwk, int format, unsigned char * output, size_t * output_len, int x5u_flags); /** * Export a jwk_t into a symmetric key in binary format * @param jwk: the jwk_t * to export * @param key: an unsigned char * that will contain the key * @param key_len: the size of key and will be set to the data size that has been written to output * @return RHN_OK on success, an error value on error * @return RHN_ERROR_PARAM if output_len isn't large enough to hold the output, then output_len will be set to the required size */ int r_jwk_export_to_symmetric_key(jwk_t * jwk, unsigned char * key, size_t * key_len); /** * Genrates a thumbprint of a jwk_t based on the RFC 7638 * @param jwk: the jwk_t * to translate into a thumbprint * @param hash: The hash funtion to use for the thumprint * Values available for this parameter are * - R_JWK_THUMB_SHA256 * - R_JWK_THUMB_SHA384 * - R_JWK_THUMB_SHA512 * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return the jwk hashed and base64url encoded on success, NULL on error, must be r_free'd after use */ char * r_jwk_thumbprint(jwk_t * jwk, int hash, int x5u_flags); /** * Verifies the certificate chain in the x5c array or the x5u * The x5c chain must be complete up to the root certificate * @param jwk: the jwk_t * to verify * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwk_validate_x5c_chain(jwk_t * jwk, int x5u_flags); /** * Search if a jwk matches the given properties * @param jwk: the jwk_t to look into * @param j_match: The query to match. Must be a JSON object with key/values * that will be compared against all keys in jwk * All parameters must match * Example, to match a RSA key with alg "RS256", the parameter j_match must contain: * {kty: "RSA", alg: "RS256"} * To match a RSA key with the kid "1", the parameter j_match must contain: * {kty: "RSA", kid: "1"} * @return RHN_OK on success * RHN_ERROR_PARAM if input parameters are invalid * RHN_ERROR_INVALID if j_match does not match */ int r_jwk_match_json_t(jwk_t * jwk, json_t * j_match); /** * Search if a jwk matches the given properties * @param jwk: the jwk_t to look into * @param str_match: The query to match. Must be a stringified JSON object with key/values * that will be compared against all keys in jwk * All parameters must match * Example, to match a RSA key with alg "RS256", the parameter str_match must contain: * {kty: "RSA", alg: "RS256"} * To match a RSA key with the kid "1", the parameter str_match must contain: * {kty: "RSA", kid: "1"} * @return RHN_OK on success * RHN_ERROR_PARAM if input parameters are invalid * RHN_ERROR_INVALID if str_match does not match */ int r_jwk_match_json_str(jwk_t * jwk, const char * str_match); /** * @} */ /** * @defgroup jwks JWKS functions * Manage JWK sets * @{ */ /** * Check if the jwks is valid * @param jwks: the jwks_t * to test * @return RHN_OK on success, an error value on error * Stops at the first error in the array * Logs error message with yder on error */ int r_jwks_is_valid(jwks_t * jwks); /** * Import a JWKS in string format into a jwks_t * @param jwks: the jwk_t * to import to * @param input: a JWKS in JSON stringified format * If jwks is set, JWK will be appended * @return RHN_OK on success, an error value on error * may return RHN_ERROR_PARAM if at least one JWK * is invalid, but the will import the others */ int r_jwks_import_from_json_str(jwks_t * jwks, const char * input); /** * Import a JWKS in json_t format into a jwk_t * @param jwks: the jwk_t * to import to * @param j_input: a JWK in json_t * format * If jwks is set, JWK will be appended * @return RHN_OK on success, an error value on error * may return RHN_ERROR_PARAM if at least one JWK * is invalid, but the will import the others */ int r_jwks_import_from_json_t(jwks_t * jwks, json_t * j_input); /** * Import a JWKS from an uri * @param jwks: the jwk_t * to import to * @param uri: an uri pointing to a JWKS * If jwks is set, JWK will be appended * @param x5u_flags: Flags to retrieve x5u certificates * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * @return RHN_OK on success, an error value on error * may return RHN_ERROR_PARAM if at least one JWK * is invalid, but the will import the others */ int r_jwks_import_from_uri(jwks_t * jwks, const char * uri, int x5u_flags); /** * Import data into a jwks * parameters must be set of values * with the mandatory parameters for each rhn_import * See rhn_import documentation * The parameters list MUST end with R_IMPORT_NONE * See rhn_import documentation * @return a jwks containing the list of keys parsed */ jwks_t * r_jwks_quick_import(rhn_import, ...); /** * Return a copy of the JWKS * @param jwks: the jwks to copy * @return a copy of the jwks */ jwks_t * r_jwks_copy(jwks_t * jwks); /** * Get the number of jwk_t in a jwks_t * @param jwks: the jwks_t * to evaluate * @return the number of jwk_t in a jwks_t */ size_t r_jwks_size(jwks_t * jwks); /** * Get the jwk_t at the specified index of the jwks_t * * @param jwks: the jwks_t * to evaluate * @param index: the index of the array to retrieve * @return a jwk_t * on success, NULL on error * The returned jwk must be r_jwk_free after use */ jwk_t * r_jwks_get_at(jwks_t * jwks, size_t index); /** * Get the jwk_t at the specified index of the jwks_t * * @param jwks: the jwks_t * to evaluate * @param kid: the key id of the jwk to retreive * @return a jwk_t * on success, NULL on error * The returned jwk must be r_jwk_free after use */ jwk_t * r_jwks_get_by_kid(jwks_t * jwks, const char * kid); /** * Append a jwk_t at the end of the array of jwk_t in the jwks_t * @param jwks: the jwks_t * to append the jwk_t * @param jwk: the jwk_t * to be appended * @return RHN_OK on success, an error value on error */ int r_jwks_append_jwk(jwks_t * jwks, jwk_t * jwk); /** * Update a jwk_t at the specified index of the jwks_t * * @param jwks: the jwks_t * to evaluate * @param jwk: the jwk_t * to set * @param index: the index of the array to update * @return RHN_OK on success, an error value on error */ int r_jwks_set_at(jwks_t * jwks, size_t index, jwk_t * jwk); /** * Remove a jwk_t at the specified index of the jwks_t * * @param jwks: the jwks_t * to evaluate * @param index: the index of the array to remove * @return RHN_OK on success, an error value on error */ int r_jwks_remove_at(jwks_t * jwks, size_t index); /** * Empty a JWKS * @param jwks: the jwks_t * to update * @return RHN_OK on success, an error value on error */ int r_jwks_empty(jwks_t * jwks); /** * Compare 2 jwks * The key content and order are compared * @param jwks1: the first JWKS to compare * @param jwks2: the second JWKS to compare * @return 1 if both jwks1 and jwks2 are equal, 0 otherwise */ int r_jwks_equal(jwks_t * jwks1, jwks_t * jwks2); /** * Export a jwks_t into a stringified JSON format * @param jwks: the jwks_t * to export * @param pretty: indent or compact JSON output * @return a char * on success, NULL on error, must be r_free'd after use */ char * r_jwks_export_to_json_str(jwks_t * jwks, int pretty); /** * Export a jwk_t into a json_t format * @param jwks: the jwk_t * to export * @return a json_t * on success, NULL on error */ json_t * r_jwks_export_to_json_t(jwks_t * jwks); /** * Export a jwks_t into a gnutls_privkey_t format * @param jwks: the jwks_t * to export * @param len: set the length of the output array * @return a heap-allocated gnutls_privkey_t * on success, NULL on error * an index of the returned array may be NULL if the corresponding jwk isn't a private key */ gnutls_privkey_t * r_jwks_export_to_gnutls_privkey(jwks_t * jwks, size_t * len); /** * Export a jwks_t into a gnutls_pubkey_t format * @param jwks: the jwks_t * to export * @param len: set the length of the output array * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return a heap-allocated gnutls_pubkey_t * on success, NULL on error */ gnutls_pubkey_t * r_jwks_export_to_gnutls_pubkey(jwks_t * jwks, size_t * len, int x5u_flags); /** * Export a jwks_t into a DER or PEM format * @param jwks: the jwks_t * to export * @param format: the format of the output, values available are R_FORMAT_PEM or R_FORMAT_DER * @param output: an unsigned char * that will contain the output * @param output_len: the size of output and will be set to the data size that has been written to output * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error * @return RHN_ERROR_PARAM if output_len isn't large enough to hold the output, then output_len will be set to the required size */ int r_jwks_export_to_pem_der(jwks_t * jwks, int format, unsigned char * output, size_t * output_len, int x5u_flags); /** * Search in a jwks_t for a subset matching the given query * @param jwks: the jwks_t to look into * @param j_match: The query to match. Must be a JSON object with key/values * that will be compared against all keys in jwks * All parameters must match * Example, to look for all RSA keys, the parameter j_match must contain: * {kty: "RSA"} * To look for all RSA keys with the kid "1", the parameter j_match must contain: * {kty: "RSA", kid: "1"} * @return a new jwks_t * containing all the matching keys, or an empty jwks_t if no match */ jwks_t * r_jwks_search_json_t(jwks_t * jwks, json_t * j_match); /** * Search in a jwks_t for a subset matching the given query * @param jwks: the jwks_t to look into * @param str_match: The query to match. Must be a stringified JSON object with key/values * that will be compared against all keys in jwks * All parameters must match * Example, to look for all RSA keys, the parameter str_match must contain: * {kty: "RSA"} * To look for all RSA keys with the kid "1", the parameter str_match must contain: * {kty: "RSA", kid: "1"} * @return a new jwks_t * containing all the matching keys, or an empty jwks_t if no match */ jwks_t * r_jwks_search_json_str(jwks_t * jwks, const char * str_match); /** * @} */ /** * @defgroup jws JWS functions * Manage JSON Web Signatures * @{ */ /** * Add multiple properties to the jws_t * * @param jws: the jws_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jws_set_properties(jws_t * jws, ...); /** * Return a copy of the JWS * @param jws: the jws_t to duplicate * @return a copy of jws */ jws_t * r_jws_copy(jws_t * jws); /** * Set the payload of the jws * @param jws: the jws_t to update * @param payload: the payload to set * @param payload_len: the size of the payload * @return RHN_OK on success, an error value on error */ int r_jws_set_payload(jws_t * jws, const unsigned char * payload, size_t payload_len); /** * Get the JWS payload * @param jws: the jws_t to get the payload from * @param payload_len: the length of the JWS payload, may be NULL * @return a pointer to the JWS payload */ const unsigned char * r_jws_get_payload(jws_t * jws, size_t * payload_len); /** * Set the JWS alg to use for signature * @param jws: the jws_t to update * @param alg: the algorithm to use * @return RHN_OK on success, an error value on error */ int r_jws_set_alg(jws_t * jws, jwa_alg alg); /** * Get the JWS alg used for signature * @param jws: the jws_t to update * @return the algorithm used */ jwa_alg r_jws_get_alg(jws_t * jws); /** * Get the KID specified in the header * used for signature * @param jws: the jws_t to update * @return the KID */ const char * r_jws_get_kid(jws_t * jws); /** * Adds a string value to the JWS header * @param jws: the jws_t to update * @param key: the key to set to the JWS header * @param str_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jws_set_header_str_value(jws_t * jws, const char * key, const char * str_value); /** * Adds an integer value to the JWS header * @param jws: the jws_t to update * @param key: the key to set to the JWS header * @param i_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jws_set_header_int_value(jws_t * jws, const char * key, rhn_int_t i_value); /** * Adds a JSON value to the JWS header * @param jws: the jws_t to update * @param key: the key to set to the JWS header * @param j_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jws_set_header_json_t_value(jws_t * jws, const char * key, json_t * j_value); /** * Sets the entire header with the JSON value specified * @param jws: the jws_t to update * @param j_value: the header to set, must be a JSON object * @return RHN_OK on success, an error value on error */ int r_jws_set_full_header_json_t(jws_t * jws, json_t * j_value); /** * Sets the entire header with the stringified JSON value specified * @param jws: the jws_t to update * @param str_value: the header to set, must be a stringified JSON object * @return RHN_OK on success, an error value on error */ int r_jws_set_full_header_json_str(jws_t * jws, const char * str_value); /** * Gets a string value from the JWS header * @param jws: the jws_t to get the value * @param key: the key to retreive the value * @return a string value, NULL if not present */ const char * r_jws_get_header_str_value(jws_t * jws, const char * key); /** * Gets an integer value from the JWS header * @param jws: the jws_t to get the value * @param key: the key to retreive the value * @return an rhn_int_t value, 0 if not present */ rhn_int_t r_jws_get_header_int_value(jws_t * jws, const char * key); /** * Gets a JSON value from the JWS header * @param jws: the jws_t to get the value * @param key: the key to retreive the value * @return a json_t * value, NULL if not present */ json_t * r_jws_get_header_json_t_value(jws_t * jws, const char * key); /** * Return the full JWS header in JSON format * @param jws: the jws_t to get the value * @return a json_t * value */ json_t * r_jws_get_full_header_json_t(jws_t * jws); /** * Return the full JWS header in char * * @param jws: the jws_t to get the value * @return a char * value, must be r_free'd after use */ char * r_jws_get_full_header_str(jws_t * jws); /** * Sets the private and public keys for the signature and verification * @param jws: the jws_t to update * @param jwk_privkey: the private key in jwk_t * format, can be NULL * @param jwk_pubkey: the public key in jwk_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jws_add_keys(jws_t * jws, jwk_t * jwk_privkey, jwk_t * jwk_pubkey); /** * Adds private and/or public keys sets for the signature and verification * @param jws: the jws_t to update * @param jwks_privkey: the private key set in jwk_t * format, can be NULL * @param jwks_pubkey: the public key set in jwk_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jws_add_jwks(jws_t * jws, jwks_t * jwks_privkey, jwks_t * jwks_pubkey); /** * Add keys to perform signature or signature verification * keys must be a JWK stringified * @param jws: the jws_t to update * @param privkey: the private key to sign * @param pubkey: the public key to verify the signature * @return RHN_OK on success, an error value on error */ int r_jws_add_keys_json_str(jws_t * jws, const char * privkey, const char * pubkey); /** * Add keys to perform signature or signature verification * keys must be a JWK in json_t * format * @param jws: the jws_t to update * @param privkey: the private key to sign the * @param pubkey: the public key to verify the signature * @return RHN_OK on success, an error value on error */ int r_jws_add_keys_json_t(jws_t * jws, json_t * privkey, json_t * pubkey); /** * Add keys to perform signature or signature verification * keys must be in PEM or DER format * @param jws: the jws_t to update * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param privkey: the private key to sign the * @param privkey_len: length of privkey * @param pubkey: the public key to verify the signature * @param pubkey_len: length of pubkey * @return RHN_OK on success, an error value on error */ int r_jws_add_keys_pem_der(jws_t * jws, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len); /** * Add keys to perform signature or signature verification * keys must be gnutls key structures * @param jws: the jws_t to update * @param privkey: the private key to sign the * @param pubkey: the public key to verify the signature * @return RHN_OK on success, an error value on error */ int r_jws_add_keys_gnutls(jws_t * jws, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); /** * Add symmetric key by value to perform signature or signature verification * @param jws: the jws_t to update * @param key: the raw key value * @param key_len: the length of the key * @return RHN_OK on success, an error value on error */ int r_jws_add_key_symmetric(jws_t * jws, const unsigned char * key, size_t key_len); /** * Get private keys set for the signature * @param jws: the jws_t to get the value * @return the private key set in jwks_t * format */ jwks_t * r_jws_get_jwks_privkey(jws_t * jws); /** * Get public keys set for the verification * @param jws: the jws_t to get the value * @return the public key set in jwks_t * format */ jwks_t * r_jws_get_jwks_pubkey(jws_t * jws); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parse(jws_t * jws, const char * jws_str, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parse(jws_t * jws, const char * jws_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * Allows to parse unsigned JWS * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parse_unsecure(jws_t * jws, const char * jws_str, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * Allows to parse unsigned JWS * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parsen_unsecure(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_compact_parse(jws_t * jws, const char * jws_str, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_compact_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_compact_parse(jws_t * jws, const char * jws_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_compact_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * Allows to parse unsigned JWS * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse * @param jws_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_compact_parsen_unsecure(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags); /** * Parses the serialized JWS in compact mode (xxx.yyy.zzz) * Allows to parse unsigned JWS * @param jws: the jws_t to update * @param jws_str: the serialized JWS to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_compact_parse_unsecure(jws_t * jws, const char * jws_str, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json_str: the serialized JWS to parse in char * format * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parse_json_str(jws_t * jws, const char * jws_json_str, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json_str: the serialized JWS to parse in char * format * @param jws_json_str_len: the length of jws_str to parse * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parsen_json_str(jws_t * jws, const char * jws_json_str, size_t jws_json_str_len, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json: the serialized JWS to parse in json_t * format * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_parse_json_t(jws_t * jws, json_t * jws_json, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json_str: the serialized JWS to parse in char * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parse_json_str(jws_t * jws, const char * jws_json_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json_str: the serialized JWS to parse in char * format * @param jws_json_str_len: the length of jws_str to parse * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parsen_json_str(jws_t * jws, const char * jws_json_str, size_t jws_json_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in JSON mode, general or flattened * @param jws: the jws_t to update * @param jws_json: the serialized JWS to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_advanced_parse_json_t(jws_t * jws, json_t * jws_json, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws_str: the serialized JWS to parse in char * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jws_t * r_jws_quick_parse(const char * jws_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWS in all modes (compact, flattened or general) * @param jws_str: the serialized JWS to parse in char * format * @param jws_str_len: the length of jws_str * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jws_t * r_jws_quick_parsen(const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags); /** * Verifies the signature of the JWS * The JWS must contain a signature * or the JWS must have alg: none * If the jws has multiple signatures, it will return RHN_OK if one signature matches * the public key * @param jws: the jws_t to update * @param jwk_pubkey: the public key to check the signature, * can be NULL if jws already contains a public key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jws_verify_signature(jws_t * jws, jwk_t * jwk_pubkey, int x5u_flags); /** * Serialize a JWS in compact mode (xxx.yyy.zzz) * @param jws: the JWS to serialize * @param jwk_privkey: the private key to use to sign the JWS * can be NULL if jws already contains a private key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return the JWS in serialized format, returned value must be r_free'd after use */ char * r_jws_serialize(jws_t * jws, jwk_t * jwk_privkey, int x5u_flags); /** * Serialize a JWS in compact mode (xxx.yyy.zzz) * Allows to serialize unsigned JWS * @param jws: the JWS to serialize * @param jwk_privkey: the private key to use to sign the JWS * can be NULL if jws already contains a private key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return the JWS in serialized format, returned value must be r_free'd after use */ char * r_jws_serialize_unsecure(jws_t * jws, jwk_t * jwk_privkey, int x5u_flags); /** * Serialize a JWS into its JSON format (general or flattened) * Mode general: Multiple signatures are generated. * You can use the jws prikeys or specify the private keys * Every jwk used to sign the jws must have a property 'alg' to specify * the signing algorithm * It is recommended, but not mandatory, to use JWKs with kid property * @param jws: the JWS to serialize * @param jwks_privkey: the private keys to use to sign the JWS * can be NULL if jws already contains a private key set * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @param mode: JSON serialization mode * Values available are * - R_JSON_MODE_GENERAL: https://tools.ietf.org/html/rfc7515#section-7.2.1 * - R_JSON_MODE_FLATTENED: https://tools.ietf.org/html/rfc7515#section-7.2.2 * @return the JWS in json_t * format, returned value must be json_decref'd after use */ json_t * r_jws_serialize_json_t(jws_t * jws, jwks_t * jwks_privkey, int x5u_flags, int mode); /** * Serialize a JWS into its JSON format (general or flattened) * Mode general: Multiple signatures are generated. * You can use the jws prikeys or specify the private keys * Every jwk used to sign the jws must have a property 'alg' to specify * the signing algorithm * It is recommended, but not mandatory, to use JWKs with kid property * @param jws: the JWS to serialize * @param jwks_privkey: the private keys to use to sign the JWS * can be NULL if jws already contains a private key set * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @param mode: JSON serialization mode * Values available are * - R_JSON_MODE_GENERAL: https://tools.ietf.org/html/rfc7515#section-7.2.1 * - R_JSON_MODE_FLATTENED: https://tools.ietf.org/html/rfc7515#section-7.2.2 * @return the JWS in char * format, returned value must be r_free'd after use */ char * r_jws_serialize_json_str(jws_t * jws, jwks_t * jwks_privkey, int x5u_flags, int mode); /** * @} */ /** * @defgroup jwe JWE functions * Manage JSON Web Encryption * @{ */ /** * Add multiple properties to the jwe_t * * @param jwe: the jwe_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jwe_set_properties(jwe_t * jwe, ...); /** * Return a copy of the JWE * @param jwe: the jwe_t to duplicate * @return a copy of jwe */ jwe_t * r_jwe_copy(jwe_t * jwe); /** * Set the payload of the jwe * @param jwe: the jwe_t to update * @param payload: the payload to set * @param payload_len: the size of the payload * @return RHN_OK on success, an error value on error */ int r_jwe_set_payload(jwe_t * jwe, const unsigned char * payload, size_t payload_len); /** * Get the JWE payload * @param jwe: the jwe_t to get the payload from * @param payload_len: the length of the JWE payload, may be NULL * @return a pointer to the JWE payload */ const unsigned char * r_jwe_get_payload(jwe_t * jwe, size_t * payload_len); /** * Set the JWE alg to use for key encryption * @param jwe: the jwe_t to update * @param alg: the algorithm to use * @return RHN_OK on success, an error value on error */ int r_jwe_set_alg(jwe_t * jwe, jwa_alg alg); /** * Get the JWE alg used for key encryption * @param jwe: the jwe_t to update * @return the algorithm used */ jwa_alg r_jwe_get_alg(jwe_t * jwe); /** * Set the JWE enc to use for payload encryption * @param jwe: the jwe_t to update * @param enc: the encorithm to use * @return RHN_OK on success, an error value on error */ int r_jwe_set_enc(jwe_t * jwe, jwa_enc enc); /** * Get the JWE enc used for payload encryption * @param jwe: the jwe_t to update * @return the encorithm used */ jwa_enc r_jwe_get_enc(jwe_t * jwe); /** * Get the KID specified in the header * for payload encryption * @param jwe: the jwe_t to update * @return the KID */ const char * r_jwe_get_kid(jwe_t * jwe); /** * Adds a string value to the JWE header * @param jwe: the jwe_t to update * @param key: the key to set to the JWE header * @param str_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwe_set_header_str_value(jwe_t * jwe, const char * key, const char * str_value); /** * Adds an integer value to the JWE header * @param jwe: the jwe_t to update * @param key: the key to set to the JWE header * @param i_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwe_set_header_int_value(jwe_t * jwe, const char * key, rhn_int_t i_value); /** * Adds a JSON value to the JWE header * @param jwe: the jwe_t to update * @param key: the key to set to the JWE header * @param j_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwe_set_header_json_t_value(jwe_t * jwe, const char * key, json_t * j_value); /** * Sets the entire header with the JSON value specified * @param jwe: the jwe_t to update * @param j_header: the header to set, must be a JSON object * @return RHN_OK on success, an error value on error */ int r_jwe_set_full_header_json_t(jwe_t * jwe, json_t * j_header); /** * Sets the entire header with the stringified JSON value specified * @param jwe: the jwe_t to update * @param str_header: the header to set, must be a stringified JSON object * @return RHN_OK on success, an error value on error */ int r_jwe_set_full_header_json_str(jwe_t * jwe, const char * str_header); /** * Sets the entire unprotected header with the JSON value specified * The unprotected header is useful when serializing in JSON format * @param jwe: the jwe_t to update * @param j_unprotected_header: the unprotected header to set, must be a JSON object * @return RHN_OK on success, an error value on error */ int r_jwe_set_full_unprotected_header_json_t(jwe_t * jwe, json_t * j_unprotected_header); /** * Sets the entire unprotected header with the stringified JSON value specified * The unprotected header is useful when serializing in JSON format * @param jwe: the jwe_t to update * @param str_unprotected_header: the unprotected header to set, must be a stringified JSON object * @return RHN_OK on success, an error value on error */ int r_jwe_set_full_unprotected_header_json_str(jwe_t * jwe, const char * str_unprotected_header); /** * Return the full JWS unprotected header in JSON format * @param jwe: the jwe_t to get the value * @return a json_t * value */ json_t * r_jwe_get_full_unprotected_header_json_t(jwe_t * jwe); /** * Return the full JWS unprotected header in char * * @param jwe: the jwe_t to get the value * @return a char * value, must be r_free'd after use */ char * r_jwe_get_full_unprotected_header_str(jwe_t * jwe); /** * Gets a string value from the JWE header * @param jwe: the jwe_t to get the value * @param key: the key to retreive the value * @return a string value, NULL if not present */ const char * r_jwe_get_header_str_value(jwe_t * jwe, const char * key); /** * Gets an integer value from the JWE header * @param jwe: the jwe_t to get the value * @param key: the key to retreive the value * @return an rhn_int_t value, 0 if not present */ rhn_int_t r_jwe_get_header_int_value(jwe_t * jwe, const char * key); /** * Gets a JSON value from the JWE header * @param jwe: the jwe_t to get the value * @param key: the key to retreive the value * @return a json_t * value, NULL if not present */ json_t * r_jwe_get_header_json_t_value(jwe_t * jwe, const char * key); /** * Return the full JWE header in JSON format * @param jwe: the jwe_t to get the value * @return a json_t * value */ json_t * r_jwe_get_full_header_json_t(jwe_t * jwe); /** * Return the full JWE header in char * * @param jwe: the jwe_t to get the value * @return a char * value, must be r_free'd after use */ char * r_jwe_get_full_header_str(jwe_t * jwe); /** * Adds private and/or public keys for the cypher key encryption and decryption * @param jwe: the jwe_t to update * @param jwk_privkey: the private key in jwk_t * format, can be NULL * @param jwk_pubkey: the public key in jwk_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jwe_add_keys(jwe_t * jwe, jwk_t * jwk_privkey, jwk_t * jwk_pubkey); /** * Adds private and/or public keys sets for the cypher key encryption and decryption * @param jwe: the jwe_t to update * @param jwks_privkey: the private key set in jwks_t * format, can be NULL * @param jwks_pubkey: the public key set in jwks_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jwe_add_jwks(jwe_t * jwe, jwks_t * jwks_privkey, jwks_t * jwks_pubkey); /** * Add keys to perform encryption ot decryption * keys must be a JWK stringified * @param jwe: the jwe_t to update * @param privkey: the private key to enc the * @param pubkey: the public key to verify the encature * @return RHN_OK on success, an error value on error */ int r_jwe_add_keys_json_str(jwe_t * jwe, const char * privkey, const char * pubkey); /** * Add keys to perform encryption ot decryption * keys must be a JWK in json_t * format * @param jwe: the jwe_t to update * @param privkey: the private key to enc the * @param pubkey: the public key to verify the encature * @return RHN_OK on success, an error value on error */ int r_jwe_add_keys_json_t(jwe_t * jwe, json_t * privkey, json_t * pubkey); /** * Add keys to perform encryption ot decryption * keys must be in PEM or DER format * @param jwe: the jwe_t to update * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param privkey: the private key to sign the * @param privkey_len: length of privkey * @param pubkey: the public key to verify the signature * @param pubkey_len: length of pubkey * @return RHN_OK on success, an error value on error */ int r_jwe_add_keys_pem_der(jwe_t * jwe, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len); /** * Add keys to perform encryption ot decryption * keys must be gnutls key structures * @param jwe: the jwe_t to update * @param privkey: the private key to enc the * @param pubkey: the public key to verify the encature * @return RHN_OK on success, an error value on error */ int r_jwe_add_keys_gnutls(jwe_t * jwe, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); /** * Add symmetric key by value to perform encryption ot decryption * @param jwe: the jwe_t to update * @param key: the raw key value * @param key_len: the length of the key * @return RHN_OK on success, an error value on error */ int r_jwe_add_key_symmetric(jwe_t * jwe, const unsigned char * key, size_t key_len); /** * Get private keys set for the cypher key decryption * @param jwe: the jwe_t to get the value * @return the private key set in jwks_t * format */ jwks_t * r_jwe_get_jwks_privkey(jwe_t * jwe); /** * Get public keys set for the cypher key encryption * @param jwe: the jwe_t to get the value * @return the public key set in jwks_t * format */ jwks_t * r_jwe_get_jwks_pubkey(jwe_t * jwe); /** * Sets the cypher key to encrypt or decrypt the payload * @param jwe: the jwe_t to update * @param key: the key to encrypt or decrypt the payload * @param key_len: the size of the key * @return RHN_OK on success, an error value on error */ int r_jwe_set_cypher_key(jwe_t * jwe, const unsigned char * key, size_t key_len); /** * Gets the cypher key to encrypt or decrypt the payload * @param jwe: the jwe_t to get the value * @param key_len: set the size of the key, may be NULL * @return the key to encrypt or decrypt the payload */ const unsigned char * r_jwe_get_cypher_key(jwe_t * jwe, size_t * key_len); /** * Generates a random cypher key * @param jwe: the jwe_t to update * @return RHN_OK on success, an error value on error */ int r_jwe_generate_cypher_key(jwe_t * jwe); /** * Sets the Initialization Vector (iv) * @param jwe: the jwe_t to update * @param iv: the iv to set * @param iv_len: the size of the iv * @return RHN_OK on success, an error value on error */ int r_jwe_set_iv(jwe_t * jwe, const unsigned char * iv, size_t iv_len); /** * Gets the Initialization Vector (iv) * @param jwe: the jwe_t to get the value * @param iv_len: set the size of the iv, may be NULL * @return the iv */ const unsigned char * r_jwe_get_iv(jwe_t * jwe, size_t * iv_len); /** * Generates a random Initialization Vector (iv) * @param jwe: the jwe_t to update * @return RHN_OK on success, an error value on error */ int r_jwe_generate_iv(jwe_t * jwe); /** * Sets the Additional Authenticated Data (aad) * @param jwe: the jwe_t to update * @param aad: the aad to set * @param aad_len: the size of the aad * @return RHN_OK on success, an error value on error */ int r_jwe_set_aad(jwe_t * jwe, const unsigned char * aad, size_t aad_len); /** * Gets the Additional Authenticated Data (aad) * @param jwe: the jwe_t to get the value * @param aad_len: set the size of the aad, may be NULL * @return the aad */ const unsigned char * r_jwe_get_aad(jwe_t * jwe, size_t * aad_len); /** * Encrypts the payload using its key and iv * @param jwe: the jwe_t to update * @return RHN_OK on success, an error value on error */ int r_jwe_encrypt_payload(jwe_t * jwe); /** * Decrypts the payload using its key and iv * @param jwe: the jwe_t to update * @return RHN_OK on success, an error value on error */ int r_jwe_decrypt_payload(jwe_t * jwe); /** * Encrypts the key * @param jwe: the jwe_t to update * @param jwk_pubkey: the jwk to encrypt the key, may be NULL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_encrypt_key(jwe_t * jwe, jwk_t * jwk_pubkey, int x5u_flags); /** * Decrypts the key * @param jwe: the jwe_t to update * @param jwk_privkey: the jwk to decrypt the key, may be NULL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_decrypt_key(jwe_t * jwe, jwk_t * jwk_privkey, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_parse(jwe_t * jwe, const char * jwe_str, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse * @param jwe_str_len: the length of jwe_str * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_parse(jwe_t * jwe, const char * jwe_str, uint32_t parse_flags, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse * @param jwe_str_len: the length of jwe_str * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the JWE in compact mode (xxx.yyy.zzz.aaa.bbb) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_compact_parse(jwe_t * jwe, const char * jwe_str, int x5u_flags); /** * Parses the JWE in compact mode (xxx.yyy.zzz.aaa.bbb) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse * @param jwe_str_len: the length of jwe_str * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_compact_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, int x5u_flags); /** * Parses the JWE in compact mode (xxx.yyy.zzz.aaa.bbb) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_compact_parse(jwe_t * jwe, const char * jwe_str, uint32_t parse_flags, int x5u_flags); /** * Parses the JWE in compact mode (xxx.yyy.zzz.aaa.bbb) * @param jwe: the jwe_t to update * @param jwe_str: the jwe serialized to parse * @param jwe_str_len: the length of jwe_str * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_compact_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json_str: the serialized JWE to parse in char * format, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_parse_json_str(jwe_t * jwe, const char * jwe_json_str, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json_str: the serialized JWE to parse in char * format * @param jwe_json_str_len: the length of jwe_json_str * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_parsen_json_str(jwe_t * jwe, const char * jwe_json_str, size_t jwe_json_str_len, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json: the serialized JWE to parse in json_t * format * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_parse_json_t(jwe_t * jwe, json_t * jwe_json, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json_str: the serialized JWE to parse in char * format, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_parse_json_str(jwe_t * jwe, const char * jwe_json_str, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json_str: the serialized JWE to parse in char * format * @param jwe_json_str_len: the length of jwe_json_str * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_parsen_json_str(jwe_t * jwe, const char * jwe_json_str, size_t jwe_json_str_len, uint32_t parse_flags, int x5u_flags); /** * Parses the serialized JWE in JSON mode, general or flattened * @param jwe: the jwe_t to update * @param jwe_json: the serialized JWE to parse in json_t * format * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_advanced_parse_json_t(jwe_t * jwe, json_t * jwe_json, uint32_t parse_flags, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe_str: the jwe serialized to parse * @param x5u_flags: Flags to retrieve x5u certificates * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwe_t * on success, NULL on error */ jwe_t * r_jwe_quick_parse(const char * jwe_str, uint32_t parse_flags, int x5u_flags); /** * Parses the JWE in all modes (compact, flattened or general) * @param jwe_str: the jwe serialized to parse * @param jwe_str_len: the length of jwe_str * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwe_t * on success, NULL on error */ jwe_t * r_jwe_quick_parsen(const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags); /** * Decrypts the payload of the JWE * @param jwe: the jwe_t to update * @param jwk_privkey: the private key to decrypt cypher key, * can be NULL if jwe already contains a private key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwe_decrypt(jwe_t * jwe, jwk_t * jwk_privkey, int x5u_flags); /** * Serialize a JWE into its string format (aaa.bbb.ccc.xxx.yyy.zzz) * @param jwe: the JWE to serialize * @param jwk_pubkey: the public key to encrypt the cypher key, * can be NULL if jwe already contains a public key * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return the JWE in serialized format, returned value must be r_free'd after use */ char * r_jwe_serialize(jwe_t * jwe, jwk_t * jwk_pubkey, int x5u_flags); /** * Serialize a JWE into its JSON format (general or flattened) * Mode general: Multiple encryptions are generated. * You can use the jwe pubkeys or specify the public keys * Every jwk used to encrypt the key must have a property 'alg' to specify * the encryption algorithm * It is recommended, but not mandatory, to use JWKs with kid property * @param jwe: the JWE to serialize * @param jwks_pubkey: the public keys to use to sign the JWE * can be NULL if jwe already contains a public key set * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @param mode: JSON serialization mode * Values available are * - R_JSON_MODE_GENERAL: https://tools.ietf.org/html/rfc7516#section-7.2.1 * - R_JSON_MODE_FLATTENED: https://tools.ietf.org/html/rfc7516#section-7.2.2 * @return the JWE in char * format, returned value must be r_free'd after use */ char * r_jwe_serialize_json_str(jwe_t * jwe, jwks_t * jwks_pubkey, int x5u_flags, int mode); /** * Serialize a JWE into its JSON format (general or flattened) * Mode general: Multiple encryptions are generated. * You can use the jwe pubkeys or specify the public keys * Every jwk used to encrypt the key must have a property 'alg' to specify * the encryption algorithm * It is recommended, but not mandatory, to use JWKs with kid property * @param jwe: the JWE to serialize * @param jwks_pubkey: the public keys to use to sign the JWE * can be NULL if jwe already contains a public key set * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @param mode: JSON serialization mode * Values available are * - R_JSON_MODE_GENERAL: https://tools.ietf.org/html/rfc7516#section-7.2.1 * - R_JSON_MODE_FLATTENED: https://tools.ietf.org/html/rfc7516#section-7.2.2 * @return the JWE in json_t * format, returned value must be json_decref'd after use */ json_t * r_jwe_serialize_json_t(jwe_t * jwe, jwks_t * jwks_pubkey, int x5u_flags, int mode); /** * @} */ /** * @defgroup jwt JWT functions * Manage JSON Web Token * @{ */ /** * Add multiple properties to the jwt_t * * @param jwt: the jwt_t to set values * @param ...: set of values using a rhn_opt and following values */ int r_jwt_set_properties(jwt_t * jwt, ...); /** * Return a copy of the JWT * @param jwt: the jwt_t to duplicate * @return a copy of jwt */ jwt_t * r_jwt_copy(jwt_t * jwt); /** * Adds a string value to the JWT header * @param jwt: the jwt_t to update * @param key: the key to set to the JWT header * @param str_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_header_str_value(jwt_t * jwt, const char * key, const char * str_value); /** * Adds an integer value to the JWT header * @param jwt: the jwt_t to update * @param key: the key to set to the JWT header * @param i_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_header_int_value(jwt_t * jwt, const char * key, rhn_int_t i_value); /** * Adds a JSON value to the JWT header * @param jwt: the jwt_t to update * @param key: the key to set to the JWT header * @param j_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_header_json_t_value(jwt_t * jwt, const char * key, json_t * j_value); /** * Sets the entire header with the JSON value specified * @param jwt: the jwt_t to update * @param j_header: the header to set, must be a JSON object * @return RHN_OK on success, an error value on error */ int r_jwt_set_full_header_json_t(jwt_t * jwt, json_t * j_header); /** * Sets the entire header with the stringified JSON value specified * @param jwt: the jwt_t to update * @param str_header: the header to set, must be a JSON object * @return RHN_OK on success, an error value on error */ int r_jwt_set_full_header_json_str(jwt_t * jwt, const char * str_header); /** * Gets a string value from the JWT header * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return a string value, NULL if not present */ const char * r_jwt_get_header_str_value(jwt_t * jwt, const char * key); /** * Gets an integer value from the JWT header * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return an rhn_int_t value, 0 if not present */ rhn_int_t r_jwt_get_header_int_value(jwt_t * jwt, const char * key); /** * Gets a JSON value from the JWT header * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return a json_t * value, NULL if not present */ json_t * r_jwt_get_header_json_t_value(jwt_t * jwt, const char * key); /** * Return the full JWT header in JSON format * @param jwt: the jwt_t to get the value * @return a json_t * value */ json_t * r_jwt_get_full_header_json_t(jwt_t * jwt); /** * Return the full JWT header in char * * @param jwt: the jwt_t to get the value * @return a char * value, must be r_free'd after use */ char * r_jwt_get_full_header_str(jwt_t * jwt); /** * Adds a string value to the JWT claim * @param jwt: the jwt_t to update * @param key: the key to set to the JWT claim * @param str_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_claim_str_value(jwt_t * jwt, const char * key, const char * str_value); /** * Adds an integer value to the JWT claim * @param jwt: the jwt_t to update * @param key: the key to set to the JWT claim * @param i_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_claim_int_value(jwt_t * jwt, const char * key, rhn_int_t i_value); /** * Adds a JSON value to the JWT claim * @param jwt: the jwt_t to update * @param key: the key to set to the JWT claim * @param j_value: the value to set * @return RHN_OK on success, an error value on error */ int r_jwt_set_claim_json_t_value(jwt_t * jwt, const char * key, json_t * j_value); /** * Gets a string value from the JWT claim * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return a string value, NULL if not present */ const char * r_jwt_get_claim_str_value(jwt_t * jwt, const char * key); /** * Gets an integer value from the JWT claim * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return an rhn_int_t value, 0 if not present */ rhn_int_t r_jwt_get_claim_int_value(jwt_t * jwt, const char * key); /** * Gets a JSON value from the JWT claim * @param jwt: the jwt_t to get the value * @param key: the key to retreive the value * @return a json_t * value, NULL if not present */ json_t * r_jwt_get_claim_json_t_value(jwt_t * jwt, const char * key); /** * Return the full JWT claim in JSON format * @param jwt: the jwt_t to get the value * @return a json_t * value */ json_t * r_jwt_get_full_claims_json_t(jwt_t * jwt); /** * Return the full JWT claims in char * * @param jwt: the jwt_t to get the value * @return a char * value, must be r_free'd after use */ char * r_jwt_get_full_claims_str(jwt_t * jwt); /** * Set the full JWT claim in JSON format * delete all existing value * @param jwt: the jwt_t to get the value * @param j_claim: the claim to set, must be JSON object * @return RHN_OK on success, an error value on error */ int r_jwt_set_full_claims_json_t(jwt_t * jwt, json_t * j_claim); /** * Set the full JWT claim in JSON format * delete all existing value * @param jwt: the jwt_t to get the value * @param str_claims: the claim to set, must be JSON object in string format * @return RHN_OK on success, an error value on error */ int r_jwt_set_full_claims_json_str(jwt_t * jwt, const char * str_claims); /** * Append the given JSON object in the JWT payload * Replace existing claim if already set * @param jwt: the jwt_t to get the value * @param j_claim: the payload to set, must be JSON object * @return RHN_OK on success, an error value on error */ int r_jwt_append_claims_json_t(jwt_t * jwt, json_t * j_claim); /** * Add keys to perform signature or signature verification to the JWT * @param jwt: the jwt_t to update * @param privkey: the private key to sign the JWT * @param pubkey: the public key to verify the JWT signature * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_keys(jwt_t * jwt, jwk_t * privkey, jwk_t * pubkey); /** * Adds private and/or public keys sets for the signature and verification * @param jwt: the jwt_t to update * @param jwks_privkey: the private key set in jwk_t * format, can be NULL * @param jwks_pubkey: the public key set in jwk_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_jwks(jwt_t * jwt, jwks_t * jwks_privkey, jwks_t * jwks_pubkey); /** * Add keys to perform signature or signature verification to the JWT * keys must be a JWK stringified * @param jwt: the jwt_t to update * @param privkey: the private key to sign the JWT * @param pubkey: the public key to verify the JWT signature * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_keys_json_str(jwt_t * jwt, const char * privkey, const char * pubkey); /** * Add keys to perform signature or signature verification to the JWT * keys must be a JWK in json_t * format * @param jwt: the jwt_t to update * @param privkey: the private key to sign the JWT * @param pubkey: the public key to verify the JWT signature * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_keys_json_t(jwt_t * jwt, json_t * privkey, json_t * pubkey); /** * Add keys to perform signature or signature verification to the JWT * keys must be in PEM or DER format * @param jwt: the jwt_t to update * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param privkey: the private key to sign the * @param privkey_len: length of privkey * @param pubkey: the public key to verify the signature * @param pubkey_len: length of pubkey * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_keys_pem_der(jwt_t * jwt, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len); /** * Add keys to perform signature or signature verification to the JWT * keys must be gnutls key structures * @param jwt: the jwt_t to update * @param privkey: the private key to sign the JWT * @param pubkey: the public key to verify the JWT signature * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_keys_gnutls(jwt_t * jwt, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); /** * Add symmetric key by value to perform signature or signature verification to the JWT * @param jwt: the jwt_t to update * @param key: the raw key value * @param key_len: the length of the key * @return RHN_OK on success, an error value on error */ int r_jwt_add_sign_key_symmetric(jwt_t * jwt, const unsigned char * key, size_t key_len); /** * Get private keys set for the signature * @param jwt: the jwt_t to get the value * @return the private key set in jwks_t * format */ jwks_t * r_jwt_get_sign_jwks_privkey(jwt_t * jwt); /** * Get public keys set for the verification * @param jwt: the jwt_t to get the value * @return the public key set in jwks_t * format */ jwks_t * r_jwt_get_sign_jwks_pubkey(jwt_t * jwt); /** * Add keys to perform encryption ot decryption to the JWT * @param jwt: the jwt_t to update * @param privkey: the private key to decrypt the JWT * @param pubkey: the public key to encrypt the JWT * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_keys(jwt_t * jwt, jwk_t * privkey, jwk_t * pubkey); /** * Adds private and/or public keys sets for the cypher key encryption and decryption * @param jwt: the jwt_t to update * @param jwks_privkey: the private key set in jwks_t * format, can be NULL * @param jwks_pubkey: the public key set in jwks_t * format, can be NULL * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_jwks(jwt_t * jwt, jwks_t * jwks_privkey, jwks_t * jwks_pubkey); /** * Add keys to perform encryption ot decryption to the JWT * keys must be a JWK stringified * @param jwt: the jwt_t to update * @param privkey: the private key to enc the JWT * @param pubkey: the public key to verify the JWT encature * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_keys_json_str(jwt_t * jwt, const char * privkey, const char * pubkey); /** * Add keys to perform encryption ot decryption to the JWT * keys must be a JWK in json_t * format * @param jwt: the jwt_t to update * @param privkey: the private key to enc the JWT * @param pubkey: the public key to verify the JWT encature * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_keys_json_t(jwt_t * jwt, json_t * privkey, json_t * pubkey); /** * Add keys to perform encryption ot decryption to the JWT * keys must be in PEM or DER format * @param jwt: the jwt_t to update * @param format: the format of the input, values available are R_FORMAT_PEM or R_FORMAT_DER * @param privkey: the private key to sign the * @param privkey_len: length of privkey * @param pubkey: the public key to verify the signature * @param pubkey_len: length of pubkey * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_keys_pem_der(jwt_t * jwt, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len); /** * Add keys to perform encryption ot decryption to the JWT * keys must be gnutls key structures * @param jwt: the jwt_t to update * @param privkey: the private key to enc the JWT * @param pubkey: the public key to verify the JWT encature * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_keys_gnutls(jwt_t * jwt, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); /** * Add symmetric key by value to perform encryption ot decryption to the JWT * @param jwt: the jwt_t to update * @param key: the raw key value * @param key_len: the length of the key * @return RHN_OK on success, an error value on error */ int r_jwt_add_enc_key_symmetric(jwt_t * jwt, const unsigned char * key, size_t key_len); /** * Get private keys set for the cypher key decryption * @param jwt: the jwt_t to get the value * @return the private key set in jwks_t * format */ jwks_t * r_jwt_get_enc_jwks_privkey(jwt_t * jwt); /** * Get public keys set for the cypher key encryption * @param jwt: the jwt_t to get the value * @return the public key set in jwks_t * format */ jwks_t * r_jwt_get_enc_jwks_pubkey(jwt_t * jwt); /** * Set the JWT alg to use for signature * @param jwt: the jwt_t to update * @param alg: the algorithm to use for signature * @return RHN_OK on success, an error value on error */ int r_jwt_set_sign_alg(jwt_t * jwt, jwa_alg alg); /** * Get the JWT alg used for signature * @param jwt: the jwt_t * @return the algorithm used for signature */ jwa_alg r_jwt_get_sign_alg(jwt_t * jwt); /** * Set the JWT alg to use for key encryption * @param jwt: the jwt_t * @param alg: the algorithm to use for key encryption * @return RHN_OK on success, an error value on error */ int r_jwt_set_enc_alg(jwt_t * jwt, jwa_alg alg); /** * Get the JWT alg used for key encryption * @param jwt: the jwt_t * @return the algorithm used for key encryption */ jwa_alg r_jwt_get_enc_alg(jwt_t * jwt); /** * Set the JWT enc to use for payload encryption * @param jwt: the jwt_t * @param enc: the encorithm to use for payload encryption * @return RHN_OK on success, an error value on error */ int r_jwt_set_enc(jwt_t * jwt, jwa_enc enc); /** * Get the JWT enc used for payload encryption * @param jwt: the jwt_t * @return the encorithm used for payload encryption */ jwa_enc r_jwt_get_enc(jwt_t * jwt); /** * Get the KID specified in the header * for payload encryption * @param jwt: the jwt_t * @return the KID */ const char * r_jwt_get_enc_kid(jwt_t * jwt); /** * Get the KID specified in the header * for signature * @param jwt: the jwt_t * @return the KID */ const char * r_jwt_get_sig_kid(jwt_t * jwt); /** * Sets the cypher key to encrypt or decrypt the payload * @param jwt: the jwt_t to update * @param key: the key to encrypt or decrypt the payload * @param key_len: the size of the key * @return RHN_OK on success, an error value on error */ int r_jwt_set_enc_cypher_key(jwt_t * jwt, const unsigned char * key, size_t key_len); /** * Gets the cypher key to encrypt or decrypt the payload * @param jwt: the jwt_t to get the value * @param key_len: set the size of the key, may be NULL * @return the key to encrypt or decrypt the payload */ const unsigned char * r_jwt_get_enc_cypher_key(jwt_t * jwt, size_t * key_len); /** * Generates a random cypher key * @param jwt: the jwt_t to update * @return RHN_OK on success, an error value on error */ int r_jwt_generate_enc_cypher_key(jwt_t * jwt); /** * Sets the Initialization Vector (iv) * @param jwt: the jwt_t to update * @param iv: the iv to set * @param iv_len: the size of the iv * @return RHN_OK on success, an error value on error */ int r_jwt_set_enc_iv(jwt_t * jwt, const unsigned char * iv, size_t iv_len); /** * Gets the Initialization Vector (iv) * @param jwt: the jwt_t to get the value * @param iv_len: set the size of the iv, may be NULL * @return the iv */ const unsigned char * r_jwt_get_enc_iv(jwt_t * jwt, size_t * iv_len); /** * Generates a random Initialization Vector (iv) * @param jwt: the jwt_t to update * @return RHN_OK on success, an error value on error */ int r_jwt_generate_iv(jwt_t * jwt); /** * Return a signed JWT in serialized format (xxx.yyy.zzz) * @param jwt: the jwt_t to sign * @param privkey: the private key to sign the JWT, may be NULL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return RHN_OK on success, an error value on error */ char * r_jwt_serialize_signed(jwt_t * jwt, jwk_t * privkey, int x5u_flags); /** * Return a signed JWT in serialized format (xxx.yyy.zzz) * Allows to serialize unsigned JWT * @param jwt: the jwt_t to sign * @param privkey: the private key to sign the JWT, may be NULL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return RHN_OK on success, an error value on error */ char * r_jwt_serialize_signed_unsecure(jwt_t * jwt, jwk_t * privkey, int x5u_flags); /** * Return an encrypted JWT in serialized format (xxx.yyy.zzz.aaa.bbb) * @param jwt: the jwt_t to encrypt * @param pubkey: the public key to encrypt the JWT, may be NULL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return RHN_OK on success, an error value on error */ char * r_jwt_serialize_encrypted(jwt_t * jwt, jwk_t * pubkey, int x5u_flags); /** * Return a nested JWT in serialized format * A nested JWT can be signed, then encrypted, or encrypted, then signed * @param jwt: the jwt_t to serialize * @param type: the nesting type * Values available are * - R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT: the JWT will be signed, then the token will be encrypted in a JWE * - R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN: The JWT will be encrypted, then the token will be signed in a JWS * @param sign_key: the key to sign the JWT, may be NULL * @param sign_key_x5u_flags: Flags to retrieve x5u certificates in sign_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @param encrypt_key: the key to encrypt the JWT, may be NULL * @param encrypt_key_x5u_flags: Flags to retrieve x5u certificates in encrypt_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return NULL * @return RHN_OK on success, an error value on error */ char * r_jwt_serialize_nested(jwt_t * jwt, unsigned int type, jwk_t * sign_key, int sign_key_x5u_flags, jwk_t * encrypt_key, int encrypt_key_x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parse(jwt_t * jwt, const char * token, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT * @param token_len: token length * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parsen(jwt_t * jwt, const char * token, size_t token_len, int x5u_flags); /** * Parses a serialized JWT * Allows to parse unsigned JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parse_unsecure(jwt_t * jwt, const char * token, int x5u_flags); /** * Parses a serialized JWT * Allows to parse unsigned JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT * @param token_len: token length * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_parsen_unsecure(jwt_t * jwt, const char * token, size_t token_len, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_advanced_parse(jwt_t * jwt, const char * token, uint32_t parse_flags, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param jwt: the jwt that will contain the parsed token * @param token: the token to parse into a JWT * @param token_len: token length * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_advanced_parsen(jwt_t * jwt, const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param token: the token to parse into a JWT, must end with a NULL string terminator * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwt_t * r_jwt_quick_parse(const char * token, uint32_t parse_flags, int x5u_flags); /** * Parses a serialized JWT * If the JWT is signed only, the claims will be available * If the JWT is encrypted, the claims will not be accessible until * r_jwt_decrypt or r_jwt_decrypt_verify_signature_nested is succesfull * @param token: the token to parse into a JWT * @param token_len: token length * @param parse_flags: Flags to set or unset options * Flags available are * - R_PARSE_NONE * - R_PARSE_HEADER_JWK * - R_PARSE_HEADER_JKU * - R_PARSE_HEADER_X5C * - R_PARSE_HEADER_X5U * - R_PARSE_HEADER_ALL * - R_PARSE_UNSIGNED * - R_PARSE_ALL * @param x5u_flags: Flags to retrieve x5u certificates * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return a new jwt_t * on success, NULL on error */ jwt_t * r_jwt_quick_parsen(const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags); /** * Get the type of JWT after a succesfull r_jwt_parse * @param jwt: the jwt_t to check * @return the type of JWT, values available are * R_JWT_TYPE_NONE: not a JWT * R_JWT_TYPE_SIGN: A signed JWT * R_JWT_TYPE_ENCRYPT: An encrypted JWT * R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT: A nested JWT first signed, then encrypted * R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN: A nested JWT first encrypted, then signed */ int r_jwt_get_type(jwt_t * jwt); /** * Guess the type of JWT based on the * token format, but without parsing the token * @param token: the token to check * @return the type of JWT, values available are * R_JWT_TYPE_NONE: not a JWT * R_JWT_TYPE_SIGN: A signed JWT * R_JWT_TYPE_ENCRYPT: An encrypted JWT */ int r_jwt_token_type(const char * token); /** * Guess the type of JWT based on the * token format, but without parsing the token * @param token: the token to check * @param token_len: token length * @return the type of JWT, values available are * R_JWT_TYPE_NONE: not a JWT * R_JWT_TYPE_SIGN: A signed JWT * R_JWT_TYPE_ENCRYPT: An encrypted JWT */ int r_jwt_token_typen(const char * token, size_t token_len); /** * Verifies the signature of the JWT * The JWT must contain a signature * or the JWT must have alg: none * @param jwt: the jwt_t to update * @param pubkey: the public key to check the signature, * can be NULL if jws already contains a public key * @param x5u_flags: Flags to retrieve x5u certificates in pubkey * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_verify_signature(jwt_t * jwt, jwk_t * pubkey, int x5u_flags); /** * Decrypts the payload of the JWT * @param jwt: the jwt_t to decrypt * @param privkey: the private key to decrypt cypher key, * can be NULL if jwt already contains a private key * @param x5u_flags: Flags to retrieve x5u certificates in privkey * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_decrypt(jwt_t * jwt, jwk_t * privkey, int x5u_flags); /** * Decrypts and verifies the signature of a nested JWT * Fills the claims if the decryption and signature verifiation are succesfull * @param jwt: the jwt_t to decrypt and verify signature * @param verify_key: the public key to check the signature, * can be NULL if jws already contains a public key * @param verify_key_x5u_flags: Flags to retrieve x5u certificates in verify_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @param decrypt_key: the private key to decrypt cypher key, * can be NULL if jwt already contains a private key * @param decrypt_key_x5u_flags: Flags to retrieve x5u certificates in decrypt_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_decrypt_verify_signature_nested(jwt_t * jwt, jwk_t * verify_key, int verify_key_x5u_flags, jwk_t * decrypt_key, int decrypt_key_x5u_flags); /** * Decrypts a nested JWT, do not verify the signature * Fills the claims if the decryption is succesfull * @param jwt: the jwt_t to decrypt and verify signature * @param decrypt_key: the private key to decrypt cypher key, * can be NULL if jwt already contains a private key * @param decrypt_key_x5u_flags: Flags to retrieve x5u certificates in decrypt_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_decrypt_nested(jwt_t * jwt, jwk_t * decrypt_key, int decrypt_key_x5u_flags); /** * Verifies the signature of a nested JWT * @param jwt: the jwt_t to decrypt and verify signature * @param verify_key: the public key to check the signature, * can be NULL if jws already contains a public key * @param verify_key_x5u_flags: Flags to retrieve x5u certificates in verify_key * pointed by x5u if necessary, could be 0 if not needed * Flags available are * - R_FLAG_IGNORE_SERVER_CERTIFICATE: ignrore if web server certificate is invalid * - R_FLAG_FOLLOW_REDIRECT: follow redirections if necessary * - R_FLAG_IGNORE_REMOTE: do not download remote key, but the function may return an error * @return RHN_OK on success, an error value on error */ int r_jwt_verify_signature_nested(jwt_t * jwt, jwk_t * verify_key, int verify_key_x5u_flags); /** * Validates the jwt claims with the list of expected claims given in parameters * The list must end with the claim type R_JWT_CLAIM_NOP * Claim types available * - R_JWT_CLAIM_ISS: claim "iss", values expected a string or NULL to validate the presence of the claim * - R_JWT_CLAIM_SUB: claim "sub", values expected a string or NULL to validate the presence of the claim * - R_JWT_CLAIM_AUD: claim "aud", values expected a string or an array of strings, or NULL to validate the presence of the claim * - R_JWT_CLAIM_EXP: claim "exp", value expected R_JWT_CLAIM_NOW or an positive integer value or R_JWT_CLAIM_PRESENT to validate the presence of the claim * - R_JWT_CLAIM_NBF: claim "nbf", value expected R_JWT_CLAIM_NOW or an positive integer value or R_JWT_CLAIM_PRESENT to validate the presence of the claim * - R_JWT_CLAIM_IAT: claim "iat", value expected R_JWT_CLAIM_NOW or an positive integer value or R_JWT_CLAIM_PRESENT to validate the presence of the claim * - R_JWT_CLAIM_JTI: claim "jti", values expected a string or NULL to validate the presence of the claim * - R_JWT_CLAIM_STR: the claim name specified must have the string value expected or NULL to validate the presence of the claim * - R_JWT_CLAIM_INT: the claim name specified must have the integer value expected * - R_JWT_CLAIM_JSN: the claim name specified must have the json_t * value expected or NULL to validate the presence of the claim * - R_JWT_CLAIM_TYP: header claim "typ", values expected a string or NULL to validate the presence of the claim * - R_JWT_CLAIM_CTY: header claim "cty", values expected a string or NULL to validate the presence of the claim * - R_JWT_CLAIM_AMR: claim "amr", values expected an array of strings, or NULL to validate the presence of the claim * Example * The following code will check the jwt agains the iss value "https://example.com", the sub value "client_1", the presence of the claim aud and that the claim exp is after now and the claim `nbf` is before now: * if (r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, "https://example.com", * R_JWT_CLAIM_SUB, "client_1", * R_JWT_CLAIM_AUD, NULL, * R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, * R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, * R_JWT_CLAIM_STR, "scope", "scope1", * R_JWT_CLAIM_INT, "age", 42, * R_JWT_CLAIM_JSN, "verified", json_true(), * R_JWT_CLAIM_NOP) == RHN_OK) */ int r_jwt_validate_claims(jwt_t * jwt, ...); /** * Set the jwt claims with the list of claims given in parameters * The list must end with the claim type R_JWT_CLAIM_NOP * Claim types available * - R_JWT_CLAIM_ISS: claim "iss", values expected a string * - R_JWT_CLAIM_SUB: claim "sub", values expected a string * - R_JWT_CLAIM_AUD: claim "aud", values expected a string * - R_JWT_CLAIM_EXP: claim "exp", value expected R_JWT_CLAIM_NOW or an positive integer value * - R_JWT_CLAIM_NBF: claim "nbf", value expected R_JWT_CLAIM_NOW or an positive integer value * - R_JWT_CLAIM_IAT: claim "iat", value expected R_JWT_CLAIM_NOW or an positive integer value * - R_JWT_CLAIM_JTI: claim "jti", values expected a string * - R_JWT_CLAIM_STR: claim name specified, then string value * - R_JWT_CLAIM_INT: claim name specified, then int value * - R_JWT_CLAIM_JSN: claim name specified, then json_t * value * - R_JWT_CLAIM_TYP: header claim "typ", values expected a string * - R_JWT_CLAIM_CTY: header claim "cty", values expected a string * - R_JWT_CLAIM_AMR: claim "amr", an array of strings, values expected a string */ int r_jwt_set_claims(jwt_t * jwt, ...); /** * @} */ #ifndef DOXYGEN_SHOULD_SKIP_THIS /** * Internal functions */ int _r_json_set_str_value(json_t * j_json, const char * key, const char * str_value); int _r_json_set_int_value(json_t * j_json, const char * key, rhn_int_t i_value); int _r_json_set_json_t_value(json_t * j_json, const char * key, json_t * j_value); const char * _r_json_get_str_value(json_t * j_json, const char * key); rhn_int_t _r_json_get_int_value(json_t * j_json, const char * key); json_t * _r_json_get_json_t_value(json_t * j_json, const char * key); json_t * _r_json_get_full_json_t(json_t * j_json); size_t _r_get_key_size(jwa_enc enc); gnutls_cipher_algorithm_t _r_get_alg_from_enc(jwa_enc enc); int _r_deflate_payload(const unsigned char * uncompressed, size_t uncompressed_len, unsigned char ** compressed, size_t * compressed_len); int _r_inflate_payload(const unsigned char * compressed, size_t compressed_len, unsigned char ** uncompressed, size_t * uncompressed_len); #endif #ifdef __cplusplus } #endif #endif // __RHONABWY_H_ rhonabwy-1.1.13/librhonabwy.pc.in000066400000000000000000000006011452472117100167000ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@PKGCONFIG_TARGET_LIBDIR@ includedir=@PKGCONFIG_TARGET_INCLUDES@ Name: @PROJECT_NAME@ Description: @PROJECT_DESCRIPTION@ URL: @PROJECT_BUGREPORT_PATH@ Version: @LIBRARY_VERSION@ Requires: @PKGCONF_REQ@ Requires.private: @PKGCONF_REQ_PRIVATE@ Libs: -L${libdir} -lrhonabwy -lorcania -lyder Cflags: -I${includedir} rhonabwy-1.1.13/src/000077500000000000000000000000001452472117100142215ustar00rootroot00000000000000rhonabwy-1.1.13/src/Makefile000066400000000000000000000110331452472117100156570ustar00rootroot00000000000000# # Rhonabwy Library # # Makefile used to build the software # # Copyright 2020-2022 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; # version 2.1 of the License. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this library. If not, see . # PROJECT_NAME=rhonabwy PROJECT_DESCRIPTION=JWK, JWKS, JWS, JWE and JWT library PROJECT_BUGREPORT_PATH=https://github.com/babelouest/rhonabwy/issues PKGCONF_REQ= PKGCONF_REQ_PRIVATE= RHONABWY_INCLUDE=../include PKGCONFIG_FILE=../librhonabwy.pc PKGCONFIG_TEMPLATE=../librhonabwy.pc.in DESTDIR=/usr/local CONFIG_FILE=$(RHONABWY_INCLUDE)/rhonabwy-cfg.h CONFIG_TEMPLATE=$(RHONABWY_INCLUDE)/rhonabwy-cfg.h.in CC=gcc CFLAGS+=-c -pedantic -std=gnu99 -fPIC -Wall -Werror -Wextra -Wconversion -D_REENTRANT -I$(RHONABWY_INCLUDE) $(ADDITIONALFLAGS) $(CPPFLAGS) LIBS=-L$(DESTDIR)/lib -lc $(shell pkg-config --libs liborcania) $(shell pkg-config --libs libyder) $(LCURL) $(shell pkg-config --libs jansson) $(shell pkg-config --libs gnutls) $(shell pkg-config --libs zlib) $(LDFLAGS) SONAME=-soname OBJECTS=jwk.o jwks.o jws.o jwe.o jwt.o misc.o OUTPUT=librhonabwy.so VERSION_MAJOR=1 VERSION_MINOR=1 VERSION_PATCH=13 ifdef DISABLE_CURL R_WITH_CURL=0 else R_WITH_CURL=1 LCURL=-lcurl endif .PHONY: all clean all: release $(CONFIG_FILE): @cp $(CONFIG_TEMPLATE) $(CONFIG_FILE) @echo Config file $(CONFIG_FILE) generated @sed -i -e 's/$${PROJECT_VERSION}/$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)/g' $(CONFIG_FILE) @sed -i -e 's/$${PROJECT_VERSION_MAJOR}/$(VERSION_MAJOR)/g' $(CONFIG_FILE) @sed -i -e 's/$${PROJECT_VERSION_MINOR}/$(VERSION_MINOR)/g' $(CONFIG_FILE) @sed -i -e 's/$${PROJECT_VERSION_PATCH}/$(VERSION_PATCH)/g' $(CONFIG_FILE) @sed -i -e 's/$${PROJECT_VERSION_NUMBER}/$(shell printf '%02d' $(VERSION_MAJOR))$(shell printf '%02d' $(VERSION_MINOR))$(shell printf '%02d' $(VERSION_PATCH))/g' $(CONFIG_FILE) @if [ "$(R_WITH_CURL)" = "1" ]; then \ sed -i -e 's/\#cmakedefine R_WITH_CURL/\#define R_WITH_CURL/g' $(CONFIG_FILE); \ echo "USE CURL ENABLED"; \ else \ sed -i -e 's/\#cmakedefine R_WITH_CURL/\/* #undef R_WITH_CURL *\//g' $(CONFIG_FILE); \ echo "USE CURL DISABLED"; \ fi $(PKGCONFIG_FILE): @cp $(PKGCONFIG_TEMPLATE) $(PKGCONFIG_FILE) @echo Pkgconfig file $(PKGCONFIG_FILE) generated @sed -i -e 's#@CMAKE_INSTALL_PREFIX@#$(DESTDIR)#g' $(PKGCONFIG_FILE) @sed -i -e 's#@PKGCONFIG_TARGET_LIBDIR@#$${prefix}/lib#g' $(PKGCONFIG_FILE) @sed -i -e 's#@PKGCONFIG_TARGET_INCLUDES@#$${prefix}/include#g' $(PKGCONFIG_FILE) @sed -i -e 's/@PROJECT_NAME@/$(PROJECT_NAME)/g' $(PKGCONFIG_FILE) @sed -i -e 's/@PROJECT_DESCRIPTION@/$(PROJECT_DESCRIPTION)/g' $(PKGCONFIG_FILE) @sed -i -e 's|@PROJECT_BUGREPORT_PATH@|$(PROJECT_BUGREPORT_PATH)|g' $(PKGCONFIG_FILE) @sed -i -e 's/@LIBRARY_VERSION@/$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)/g' $(PKGCONFIG_FILE) @sed -i -e 's/@PKGCONF_REQ@/$(PKGCONF_REQ)/g' $(PKGCONFIG_FILE) @sed -i -e 's/@PKGCONF_REQ_PRIVATE@/$(PKGCONF_REQ_PRIVATE)/g' $(PKGCONFIG_FILE) target: $(OBJECTS) %.o: %.c $(RHONABWY_INCLUDE)/rhonabwy.h $(CC) $(CFLAGS) $< librhonabwy.so: $(CONFIG_FILE) $(OBJECTS) $(CC) -shared -fPIC -Wl,$(SONAME),$(OUTPUT) -o $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(OBJECTS) $(LIBS) ln -sf $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(OUTPUT) clean: rm -f *.o *.so *.a $(OUTPUT) $(OUTPUT).* $(PKGCONFIG_FILE) $(CONFIG_FILE) install: all $(PKGCONFIG_FILE) install $(OUTPUT).$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH) $(DESTDIR)/lib mkdir -p $(DESTDIR)/lib/pkgconfig/ $(DESTDIR)/include install -m644 $(PKGCONFIG_FILE) $(DESTDIR)/lib/pkgconfig/ install -m644 $(RHONABWY_INCLUDE)/rhonabwy.h $(DESTDIR)/include install -m644 $(CONFIG_FILE) $(DESTDIR)/include -ldconfig $(DESTDIR)/lib uninstall: rm -f $(DESTDIR)/lib/$(OUTPUT) $(DESTDIR)/lib/librhonabwy.a rm -f $(DESTDIR)/lib/$(OUTPUT).* rm -f $(DESTDIR)/include/rhonabwy.h rm -f $(DESTDIR)/include/$(CONFIG_FILE) rm -f $(DESTDIR)/lib/pkgconfig/$(PKGCONFIG_FILE) debug: ADDITIONALFLAGS=-DDEBUG -g -O0 debug: librhonabwy.so release: ADDITIONALFLAGS=-O3 release: librhonabwy.so rhonabwy-1.1.13/src/jwe.c000066400000000000000000005300601452472117100151560ustar00rootroot00000000000000/** * * Rhonabwy JSON Web Encryption (JWE) library * * jwe.c: functions definitions * * Copyright 2020-2022 Nicolas Mora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include #include #include #include #include #include #include #define R_TAG_MAX_SIZE 16 #define _R_BLOCK_SIZE 256 #define _R_PBES_DEFAULT_ITERATION 4096 #define _R_PBES_DEFAULT_SALT_LENGTH 8 #define _R_CURVE_MAX_SIZE 66 // AES KeyWrap (includes) #if NETTLE_VERSION_NUMBER >= 0x030400 #include #include #include #include #endif // RSA OAEP (includes) #if NETTLE_VERSION_NUMBER >= 0x030400 #include #include #endif // ECDH key management (includes) #if NETTLE_VERSION_NUMBER >= 0x030600 #include #include #include #include #include #include #endif // RSA OAEP // https://git.lysator.liu.se/nettle/nettle/-/merge_requests/20 #if NETTLE_VERSION_NUMBER >= 0x030400 int pkcs1_eme_oaep_decode (size_t key_size, const mpz_t m, /* Hash function */ size_t hlen, void * ctx, const struct nettle_hash *hash, nettle_hash_init_func *hash_init, nettle_hash_update_func *hash_update, nettle_hash_digest_func *hash_digest, size_t label_length, const uint8_t *label, size_t *length, uint8_t *message) { int ret = 1; size_t dbMask_len = key_size-1-hlen, i; uint8_t lHash[hlen], k[hlen], seedMask[hlen], maskedSeed[hlen]; uint8_t *em, *maskedDB, *dbMask, *db; em = o_malloc(key_size); maskedDB = o_malloc(dbMask_len); dbMask = o_malloc(dbMask_len); db = o_malloc(dbMask_len); // lHash = Hash(L) hash_init(ctx); hash_update(ctx, label_length, label); hash_digest(ctx, hlen, lHash); nettle_mpz_get_str_256(key_size, em, m); if (em[0]) { ret = 0; } memcpy(maskedSeed, em+1, hlen); memcpy(maskedDB, em+1+hlen, key_size-1-hlen); // seedMask = MGF(maskedDB, hLen). hash_init(ctx); hash_update(ctx, dbMask_len, maskedDB); pss_mgf1(ctx, hash, hlen, seedMask); // seed = maskedSeed \xor seedMask. for (i=0; i= dbMask_len-i-1 && i < dbMask_len-1) { *length = dbMask_len-i-1; memcpy(message, db+i+1, *length); } else { ret = 0; } o_free(em); o_free(maskedDB); o_free(dbMask); o_free(db); return ret; } int rsaes_oaep_sha1_decrypt(const struct rsa_private_key *key, size_t label_length, const uint8_t *label, size_t *length, uint8_t *message, const mpz_t gibberish) { mpz_t m; int res; struct sha1_ctx ctx; if (nettle_mpz_sizeinbase_256_u (gibberish) > key->size || key->size < (2*SHA1_DIGEST_SIZE)+2) { return 0; } mpz_init(m); rsa_compute_root(key, m, gibberish); res = pkcs1_eme_oaep_decode (key->size, m, SHA1_DIGEST_SIZE, &ctx, &nettle_sha1, (nettle_hash_init_func*)&sha1_init, (nettle_hash_update_func*)&sha1_update, (nettle_hash_digest_func*)&sha1_digest, label_length, label, length, message); mpz_clear(m); return res; } int rsaes_oaep_sha256_decrypt(const struct rsa_private_key *key, size_t label_length, const uint8_t *label, size_t *length, uint8_t *message, const mpz_t gibberish) { mpz_t m; int res; struct sha256_ctx ctx; if (nettle_mpz_sizeinbase_256_u (gibberish) > key->size || key->size < (2*SHA256_DIGEST_SIZE)+2) { return 0; } mpz_init(m); rsa_compute_root(key, m, gibberish); res = pkcs1_eme_oaep_decode (key->size, m, SHA256_DIGEST_SIZE, &ctx, &nettle_sha256, (nettle_hash_init_func*)&sha256_init, (nettle_hash_update_func*)&sha256_update, (nettle_hash_digest_func*)&sha256_digest, label_length, label, length, message); mpz_clear(m); return res; } int pkcs1_eme_oaep_encode (size_t key_size, void *random_ctx, nettle_random_func *random, /* Hash function */ size_t hlen, void * ctx, const struct nettle_hash *hash, nettle_hash_init_func *hash_init, nettle_hash_update_func *hash_update, nettle_hash_digest_func *hash_digest, size_t label_length, const uint8_t *label, size_t message_length, const uint8_t *message, mpz_t m) { size_t ps_len = key_size - message_length - (2*hlen) - 2, dbMask_len = key_size - hlen - 1, i; uint8_t lHash[hlen], k[hlen], seedMask[hlen], maskedSeed[hlen]; int ret = 1; if (key_size < (2*hlen) - 2 || message_length > key_size - (2*hlen) - 2) { return 0; } uint8_t *em, *maskedDB, *dbMask, *db; em = o_malloc(dbMask_len + hlen + 1); maskedDB = o_malloc(dbMask_len); dbMask = o_malloc(dbMask_len); db = o_malloc(dbMask_len); // lHash = Hash(L) hash_init(ctx); hash_update(ctx, label_length, label); hash_digest(ctx, hlen, lHash); // DB = lHash || PS || 0x01 || M. memcpy(db, lHash, hlen); memset(db+hlen, 0, ps_len); memset(db+hlen+ps_len, 1, 1); memcpy(db+hlen+ps_len+1, message, message_length); random(random_ctx, hlen, k); // dbMask = MGF(seed, k - hLen - 1). hash_init(ctx); hash_update(ctx, hlen, k); pss_mgf1(ctx, hash, dbMask_len, dbMask); // maskedDB = DB \xor dbMask. for (i=0; isize, random_ctx, random, SHA1_DIGEST_SIZE, &ctx, &nettle_sha1, (nettle_hash_init_func*)&sha1_init, (nettle_hash_update_func*)&sha1_update, (nettle_hash_digest_func*)&sha1_digest, label_length, label, length, message, gibberish)) { mpz_powm(gibberish, gibberish, key->e, key->n); return 1; } else return 0; } int rsaes_oaep_sha256_encrypt(const struct rsa_public_key *key, void *random_ctx, nettle_random_func *random, size_t label_length, const uint8_t *label, size_t length, const uint8_t *message, mpz_t gibberish) { struct sha256_ctx ctx; if (pkcs1_eme_oaep_encode (key->size, random_ctx, random, SHA256_DIGEST_SIZE, &ctx, &nettle_sha256, (nettle_hash_init_func*)&sha256_init, (nettle_hash_update_func*)&sha256_update, (nettle_hash_digest_func*)&sha256_digest, label_length, label, length, message, gibberish)) { mpz_powm(gibberish, gibberish, key->e, key->n); return 1; } else return 0; } static void rnd_nonce_func(void *_ctx, size_t length, uint8_t * data) { (void)_ctx; gnutls_rnd(GNUTLS_RND_NONCE, data, length); } static int _r_rsa_oaep_encrypt(gnutls_pubkey_t g_pub, jwa_alg alg, uint8_t * cleartext, size_t cleartext_len, uint8_t * ciphertext, size_t * cyphertext_len) { struct rsa_public_key pub; gnutls_datum_t m = {NULL, 0}, e = {NULL, 0}; int ret = RHN_OK; mpz_t gibberish; rsa_public_key_init(&pub); mpz_init(gibberish); if (gnutls_pubkey_export_rsa_raw(g_pub, &m, &e) == GNUTLS_E_SUCCESS) { mpz_import(pub.n, m.size, 1, 1, 0, 0, m.data); mpz_import(pub.e, e.size, 1, 1, 0, 0, e.data); rsa_public_key_prepare(&pub); if (*cyphertext_len >= pub.size) { if (alg == R_JWA_ALG_RSA_OAEP) { if (!rsaes_oaep_sha1_encrypt(&pub, NULL, rnd_nonce_func, 0, NULL, cleartext_len, cleartext, gibberish)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_encrypt - Error rsaes_oaep_sha1_encrypt"); ret = RHN_ERROR; } } else { if (!rsaes_oaep_sha256_encrypt(&pub, NULL, rnd_nonce_func, 0, NULL, cleartext_len, cleartext, gibberish)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_encrypt - Error rsaes_oaep_sha256_encrypt"); ret = RHN_ERROR; } } if (ret == RHN_OK) { nettle_mpz_get_str_256(pub.size, ciphertext, gibberish); *cyphertext_len = pub.size; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_encrypt - Error cyphertext to small"); ret = RHN_ERROR_PARAM; } gnutls_free(m.data); gnutls_free(e.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_encrypt - Error gnutls_pubkey_export_rsa_raw"); ret = RHN_ERROR; } rsa_public_key_clear(&pub); mpz_clear(gibberish); return ret; } static int _r_rsa_oaep_decrypt(gnutls_privkey_t g_priv, jwa_alg alg, uint8_t * ciphertext, size_t cyphertext_len, uint8_t * cleartext, size_t * cleartext_len) { struct rsa_private_key priv; gnutls_datum_t m = {NULL, 0}, e = {NULL, 0}, d = {NULL, 0}, p = {NULL, 0}, q = {NULL, 0}, u = {NULL, 0}, e1 = {NULL, 0}, e2 = {NULL, 0}; int ret = RHN_OK; mpz_t gibberish; rsa_private_key_init(&priv); mpz_init(gibberish); nettle_mpz_set_str_256_u(gibberish, cyphertext_len, ciphertext); if (gnutls_privkey_export_rsa_raw(g_priv, &m, &e, &d, &p, &q, &u, &e1, &e2) == GNUTLS_E_SUCCESS) { mpz_import(priv.d, d.size, 1, 1, 0, 0, d.data); mpz_import(priv.p, p.size, 1, 1, 0, 0, p.data); mpz_import(priv.q, q.size, 1, 1, 0, 0, q.data); mpz_import(priv.a, e1.size, 1, 1, 0, 0, e1.data); mpz_import(priv.b, e2.size, 1, 1, 0, 0, e2.data); mpz_import(priv.c, u.size, 1, 1, 0, 0, u.data); rsa_private_key_prepare(&priv); if (cyphertext_len >= priv.size) { if (alg == R_JWA_ALG_RSA_OAEP) { if (!rsaes_oaep_sha1_decrypt(&priv, 0, NULL, cleartext_len, cleartext, gibberish)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_decrypt - Error rsaes_oaep_sha1_decrypt"); ret = RHN_ERROR; } } else { if (!rsaes_oaep_sha256_decrypt(&priv, 0, NULL, cleartext_len, cleartext, gibberish)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_decrypt - Error rsaes_oaep_sha256_decrypt"); ret = RHN_ERROR; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_decrypt - Error cyphertext to small"); ret = RHN_ERROR_PARAM; } gnutls_free(m.data); gnutls_free(e.data); gnutls_free(d.data); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(u.data); gnutls_free(e1.data); gnutls_free(e2.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_rsa_oaep_encrypt - Error gnutls_pubkey_export_rsa_raw"); ret = RHN_ERROR; } rsa_private_key_clear(&priv); mpz_clear(gibberish); return ret; } #endif // AES KeyWrap // https://git.lysator.liu.se/nettle/nettle/-/merge_requests/19 #if NETTLE_VERSION_NUMBER >= 0x030400 static void nist_keywrap16(const void *ctx, nettle_cipher_func *encrypt, const uint8_t *iv, size_t ciphertext_length, uint8_t *ciphertext, const uint8_t *cleartext) { uint8_t * R = NULL, A[8] = {0}, I[16] = {0}, B[16] = {0}; uint64_t A64; size_t i, j, n; if ((R = o_malloc(ciphertext_length-8)) == NULL) return; n = (ciphertext_length-8)/8; memcpy(R, cleartext, (ciphertext_length-8)); memcpy(A, iv, 8); for (j=0; j<6; j++) { for (i=0; i> 8); A[5] = (uint8_t)(A64 >> 16); A[4] = (uint8_t)(A64 >> 24); A[3] = (uint8_t)(A64 >> 32); A[2] = (uint8_t)(A64 >> 40); A[1] = (uint8_t)(A64 >> 48); A[0] = (uint8_t)(A64 >> 56); // R[i] = LSB(64, B) memcpy(R+(i*8), B+8, 8); } } memcpy(ciphertext, A, 8); memcpy(ciphertext+8, R, (ciphertext_length-8)); o_free(R); } static int nist_keyunwrap16(const void *ctx, nettle_cipher_func *decrypt, const uint8_t *iv, size_t cleartext_length, uint8_t *cleartext, const uint8_t *ciphertext) { uint8_t * R = NULL, A[8] = {0}, I[16] = {0}, B[16] = {0}; uint64_t A64; int i, j, ret; size_t n; if ((R = o_malloc(cleartext_length)) == NULL) return 0; n = (cleartext_length/8); memcpy(A, ciphertext, 8); memcpy(R, ciphertext+8, cleartext_length); for (j=5; j>=0; j--) { for (i=(int)n-1; i>=0; i--) { // B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i A64 = ((uint64_t)A[0] << 56) | ((uint64_t)A[1] << 48) | ((uint64_t)A[2] << 40) | ((uint64_t)A[3] << 32) | ((uint64_t)A[4] << 24) | ((uint64_t)A[5] << 16) | ((uint64_t)A[6] << 8) | (uint64_t)A[7]; A64 ^= (uint64_t)((n*(size_t)j)+(size_t)(i+1)); I[7] = (uint8_t)A64; I[6] = (uint8_t)(A64 >> 8); I[5] = (uint8_t)(A64 >> 16); I[4] = (uint8_t)(A64 >> 24); I[3] = (uint8_t)(A64 >> 32); I[2] = (uint8_t)(A64 >> 40); I[1] = (uint8_t)(A64 >> 48); I[0] = (uint8_t)(A64 >> 56); memcpy(I+8, R+(i*8), 8); decrypt(ctx, 16, B, I); // A = MSB(64, B) memcpy(A, B, 8); // R[i] = LSB(64, B) memcpy(R+(i*8), B+8, 8); } } if (memeql_sec(A, iv, 8)) { memcpy(cleartext, R, cleartext_length); ret = 1; } else { ret = 0; } o_free(R); return ret; } static void _r_aes_key_wrap(uint8_t * kek, size_t kek_len, uint8_t * key, size_t key_len, uint8_t * wrapped_key) { struct aes128_ctx ctx_128; struct aes192_ctx ctx_192; struct aes256_ctx ctx_256; void * ctx = NULL; nettle_cipher_func * encrypt = NULL; const uint8_t default_iv[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; if (kek_len == 16) { aes128_set_encrypt_key(&ctx_128, kek); ctx = (void*)&ctx_128; encrypt = (nettle_cipher_func*)&aes128_encrypt; } if (kek_len == 24) { aes192_set_encrypt_key(&ctx_192, kek); ctx = (void*)&ctx_192; encrypt = (nettle_cipher_func*)&aes192_encrypt; } if (kek_len == 32) { aes256_set_encrypt_key(&ctx_256, kek); ctx = (void*)&ctx_256; encrypt = (nettle_cipher_func*)&aes256_encrypt; } nist_keywrap16(ctx, encrypt, default_iv, key_len+8, wrapped_key, key); } static int _r_aes_key_unwrap(uint8_t * kek, size_t kek_len, uint8_t * key, size_t key_len, uint8_t * wrapped_key) { struct aes128_ctx ctx_128; struct aes192_ctx ctx_192; struct aes256_ctx ctx_256; void * ctx = NULL; nettle_cipher_func * decrypt = NULL; const uint8_t default_iv[] = {0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}; if (kek_len == 16) { aes128_set_decrypt_key(&ctx_128, kek); ctx = (void*)&ctx_128; decrypt = (nettle_cipher_func*)&aes128_decrypt; } if (kek_len == 24) { aes192_set_decrypt_key(&ctx_192, kek); ctx = (void*)&ctx_192; decrypt = (nettle_cipher_func*)&aes192_decrypt; } if (kek_len == 32) { aes256_set_decrypt_key(&ctx_256, kek); ctx = (void*)&ctx_256; decrypt = (nettle_cipher_func*)&aes256_decrypt; } return nist_keyunwrap16(ctx, decrypt, default_iv, key_len, key, wrapped_key); } static json_t * r_jwe_aes_key_wrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags, int * ret) { uint8_t kek[32] = {0}, wrapped_key[72] = {0}; unsigned char cipherkey_b64url[256] = {0}; size_t kek_len = 32, cipherkey_b64url_len = 0; unsigned int bits = 0; json_t * j_return = NULL; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { do { if (alg == R_JWA_ALG_A128KW && bits != 128) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error invalid key size, expected 128 bits"); *ret = RHN_ERROR_PARAM; break; } if (alg == R_JWA_ALG_A192KW && bits != 192) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error invalid key size, expected 192 bits"); *ret = RHN_ERROR_PARAM; break; } if (alg == R_JWA_ALG_A256KW && bits != 256) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error invalid key size, expected 256 bits"); *ret = RHN_ERROR_PARAM; break; } if (r_jwk_export_to_symmetric_key(jwk, kek, &kek_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error r_jwk_export_to_symmetric_key"); *ret = RHN_ERROR; break; } _r_aes_key_wrap(kek, kek_len, jwe->key, jwe->key_len, wrapped_key); if (!o_base64url_encode(wrapped_key, jwe->key_len+8, cipherkey_b64url, &cipherkey_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error o_base64url_encode wrapped_key"); *ret = RHN_ERROR; break; } j_return = json_pack("{ss%s{ss}}", "encrypted_key", cipherkey_b64url, cipherkey_b64url_len, "header", "alg", r_jwa_alg_to_str(alg)); o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = (unsigned char *)o_strndup((const char *)cipherkey_b64url, cipherkey_b64url_len); } while (0); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error invalid key"); *ret = RHN_ERROR_PARAM; } return j_return; } static int r_jwe_aes_key_unwrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags) { int ret; uint8_t kek[32] = {0}, key_data[64], cipherkey[128] = {0}; size_t kek_len = 32, cipherkey_len = 0; unsigned int bits = 0; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { ret = RHN_OK; do { if (alg == R_JWA_ALG_A128KW && bits != 128) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error invalid key size, expected 128 bits"); ret = RHN_ERROR_INVALID; break; } if (alg == R_JWA_ALG_A192KW && bits != 192) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error invalid key size, expected 192 bits"); ret = RHN_ERROR_INVALID; break; } if (alg == R_JWA_ALG_A256KW && bits != 256) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error invalid key size, expected 256 bits"); ret = RHN_ERROR_INVALID; break; } if (r_jwk_export_to_symmetric_key(jwk, kek, &kek_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error r_jwk_export_to_symmetric_key"); ret = RHN_ERROR; break; } if (!o_base64url_decode(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), NULL, &cipherkey_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error o_base64url_decode cipherkey"); ret = RHN_ERROR_INVALID; break; } if (cipherkey_len > 72) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error invalid cipherkey len"); ret = RHN_ERROR_INVALID; break; } if (!o_base64url_decode(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), cipherkey, &cipherkey_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error o_base64url_decode cipherkey"); ret = RHN_ERROR_INVALID; break; } if (!_r_aes_key_unwrap(kek, kek_len, key_data, cipherkey_len-8, cipherkey)) { ret = RHN_ERROR_INVALID; break; } if (r_jwe_set_cypher_key(jwe, key_data, cipherkey_len-8) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error r_jwe_set_cypher_key"); ret = RHN_ERROR; } } while (0); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_unwrap - Error invalid key"); ret = RHN_ERROR_INVALID; } return ret; } #endif // ECDH key management #if NETTLE_VERSION_NUMBER >= 0x030600 static int _r_concat_kdf(jwe_t * jwe, jwa_alg alg, const gnutls_datum_t * Z, gnutls_datum_t * kdf, uint8_t * derived_key) { int ret = RHN_OK; struct _o_datum dat_apu = {0, NULL}, dat_apv = {0, NULL}; const char * alg_id = alg==R_JWA_ALG_ECDH_ES?r_jwa_enc_to_str(jwe->enc):r_jwa_alg_to_str(alg), * apu = r_jwe_get_header_str_value(jwe, "apu"), * apv = r_jwe_get_header_str_value(jwe, "apv"); size_t alg_id_len = o_strlen(alg_id), key_data_len = 0; size_t derived_key_len = _r_get_key_size(jwe->enc); size_t current_key_len = 0; uint8_t i; kdf->data = NULL; kdf->size = 0; do { if ((kdf->data = o_malloc(4+Z->size)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error malloc kdf->data"); ret = RHN_ERROR_MEMORY; break; } memset(kdf->data, 0, 3); memset(kdf->data+3, 1, 1); memcpy(kdf->data+4, Z->data, Z->size); kdf->size = 4+Z->size; if ((kdf->data = o_realloc(kdf->data, kdf->size+4+alg_id_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error realloc kdf->data (1)"); ret = RHN_ERROR_MEMORY; break; } memset(kdf->data+kdf->size, 0, 3); memset(kdf->data+kdf->size+3, (uint8_t)alg_id_len, 1); memcpy(kdf->data+kdf->size+4, alg_id, alg_id_len); kdf->size += 4+(unsigned int)alg_id_len; if (!o_strnullempty(apu)) { if (!o_base64url_decode_alloc((const unsigned char *)apu, o_strlen(apu), &dat_apu)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error o_base64url_decode_alloc apu"); ret = RHN_ERROR; break; } } if ((kdf->data = o_realloc(kdf->data, kdf->size+4+dat_apu.size)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error realloc kdf->data (2)"); ret = RHN_ERROR_MEMORY; break; } kdf->data[kdf->size] = (unsigned char)(dat_apu.size>>24) & 0xFF; kdf->data[kdf->size+1] = (unsigned char)(dat_apu.size>>16) & 0xFF; kdf->data[kdf->size+2] = (unsigned char)(dat_apu.size>>8) & 0xFF; kdf->data[kdf->size+3] = (unsigned char)(dat_apu.size) & 0xFF; if (dat_apu.size) { memcpy(kdf->data+kdf->size+4, dat_apu.data, dat_apu.size); } kdf->size += (unsigned int)dat_apu.size+4; if (!o_strnullempty(apv)) { if (!o_base64url_decode_alloc((const unsigned char *)apv, o_strlen(apv), &dat_apv)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error o_base64url_decode apv"); ret = RHN_ERROR; break; } } if ((kdf->data = o_realloc(kdf->data, kdf->size+4+dat_apv.size)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error realloc kdf->data (3)"); ret = RHN_ERROR_MEMORY; break; } kdf->data[kdf->size] = (unsigned char)(dat_apv.size>>24) & 0xFF; kdf->data[kdf->size+1] = (unsigned char)(dat_apv.size>>16) & 0xFF; kdf->data[kdf->size+2] = (unsigned char)(dat_apv.size>>8) & 0xFF; kdf->data[kdf->size+3] = (unsigned char)(dat_apv.size) & 0xFF; if (dat_apv.size) { memcpy(kdf->data+kdf->size+4, dat_apv.data, dat_apv.size); } kdf->size += (unsigned int)dat_apv.size+4; if (alg == R_JWA_ALG_ECDH_ES) { key_data_len = _r_get_key_size(jwe->enc)*8; } else if (alg == R_JWA_ALG_ECDH_ES_A128KW) { key_data_len = 16*8; } else if (alg == R_JWA_ALG_ECDH_ES_A192KW) { key_data_len = 24*8; } else if (alg == R_JWA_ALG_ECDH_ES_A256KW) { key_data_len = 32*8; } if (!key_data_len) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error invalid keydatalen"); ret = RHN_ERROR; break; } if ((kdf->data = o_realloc(kdf->data, kdf->size+4)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error realloc kdf->data (4)"); ret = RHN_ERROR_MEMORY; break; } kdf->data[kdf->size] = (unsigned char)(key_data_len>>24) & 0xFF; kdf->data[kdf->size+1] = (unsigned char)(key_data_len>>16) & 0xFF; kdf->data[kdf->size+2] = (unsigned char)(key_data_len>>8) & 0xFF; kdf->data[kdf->size+3] = (unsigned char)(key_data_len) & 0xFF; kdf->size += 4; for (i = 1; ; i++) { memset(kdf->data+3, i, 1); if (gnutls_hash_fast(GNUTLS_DIG_SHA256, kdf->data, kdf->size, derived_key+current_key_len) != GNUTLS_E_SUCCESS) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_concat_kdf - Error gnutls_hash_fast"); ret = RHN_ERROR; break; } current_key_len += gnutls_hash_get_len(GNUTLS_DIG_SHA256); // GNUTLS_DIG_SHA256 hash size if (alg != R_JWA_ALG_ECDH_ES || current_key_len >= derived_key_len) { break; } } // This is set to make sure that the 'do while(0)' is interrupted if the gnutls_hash_fast below fails // Even if soe code is added after this point in a hypothetic future if (ret != RHN_OK) { break; } } while (0); o_free(dat_apu.data); o_free(dat_apv.data); if (ret != RHN_OK) { o_free(kdf->data); kdf->data = NULL; kdf->size = 0; } return ret; } static int _r_ecdh_compute(uint8_t * priv_d, size_t priv_d_size, uint8_t * pub_x, size_t pub_x_size, uint8_t * pub_y, size_t pub_y_size, const struct ecc_curve * curve, gnutls_datum_t * Z) { int ret = RHN_OK; struct ecc_scalar priv; struct ecc_point pub, r; mpz_t z_priv_d, z_pub_x, z_pub_y, r_x, r_y; uint8_t r_x_u[64] = {0}; size_t r_x_u_len = 64; mpz_init(z_priv_d); mpz_init(z_pub_x); mpz_init(z_pub_y); mpz_init(r_x); mpz_init(r_y); ecc_scalar_init(&priv, curve); ecc_point_init(&pub, curve); ecc_point_init(&r, curve); do { mpz_import(z_priv_d, priv_d_size, 1, 1, 0, 0, priv_d); if (!ecc_scalar_set(&priv, z_priv_d)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_ecdh_compute - Error ecc_scalar_set"); ret = RHN_ERROR_INVALID; break; } mpz_import(z_pub_x, pub_x_size, 1, 1, 0, 0, pub_x); mpz_import(z_pub_y, pub_y_size, 1, 1, 0, 0, pub_y); if (!ecc_point_set(&pub, z_pub_x, z_pub_y)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_ecdh_compute - Error ecc_point_set"); ret = RHN_ERROR; break; } ecc_point_mul(&r, &priv, &pub); ecc_point_get(&r, r_x, r_y); mpz_export(r_x_u, &r_x_u_len, 1, 1, 0, 0, r_x); if ((Z->data = gnutls_malloc(r_x_u_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_ecdh_compute - Error gnutls_malloc"); ret = RHN_ERROR_MEMORY; break; } memcpy(Z->data, r_x_u, r_x_u_len); Z->size = (unsigned int)r_x_u_len; ret = RHN_OK; } while (0); mpz_clear(z_priv_d); mpz_clear(z_pub_x); mpz_clear(z_pub_y); mpz_clear(r_x); mpz_clear(r_y); ecc_scalar_clear(&priv); ecc_point_clear(&pub); ecc_point_clear(&r); return ret; } static int _r_dh_compute(uint8_t * priv_k, uint8_t * pub_x, size_t crv_size, gnutls_datum_t * Z) { int ret; uint8_t q[CURVE448_SIZE] = {0}; if (crv_size == CURVE25519_SIZE) { curve25519_mul(q, priv_k, pub_x); } else { curve448_mul(q, priv_k, pub_x); } if ((Z->data = gnutls_malloc(crv_size)) != NULL) { memcpy(Z->data, q, crv_size); Z->size = (unsigned int)crv_size; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_dh_compute - Error gnutls_malloc"); ret = RHN_ERROR_MEMORY; } return ret; } static int _r_compare_likely(size_t src, size_t around) { return ((around && src == around-1) || src == around || src == around+1); } static json_t * _r_jwe_ecdh_encrypt(jwe_t * jwe, jwa_alg alg, jwk_t * jwk_pub, jwk_t * jwk_priv, int type, unsigned int bits, int x5u_flags, int * ret) { int type_priv = 0; unsigned int bits_priv = 0; jwk_t * jwk_ephemeral = NULL, * jwk_ephemeral_pub = NULL; gnutls_datum_t Z = {NULL, 0}, kdf = {NULL, 0}; unsigned char cipherkey_b64url[256] = {0}; uint8_t derived_key[128] = {0}, wrapped_key[136] = {0}, priv_k[_R_CURVE_MAX_SIZE] = {0}, pub_x[_R_CURVE_MAX_SIZE] = {0}, pub_y[_R_CURVE_MAX_SIZE] = {0}; size_t derived_key_len = 0, cipherkey_b64url_len = 0, priv_k_size = 0, pub_x_size = 0, pub_y_size = 0, crv_size = 0; const char * key = NULL; json_t * j_return = NULL; const struct ecc_curve * nettle_curve; gnutls_ecc_curve_t curve = GNUTLS_ECC_CURVE_INVALID; do { if (r_jwk_init(&jwk_ephemeral_pub) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error r_jwk_init jwk_ephemeral_pub"); *ret = RHN_ERROR; break; } if (jwk_priv != NULL) { type_priv = r_jwk_key_type(jwk_priv, &bits_priv, x5u_flags); if (((unsigned int)type_priv & 0xffffff00) != ((unsigned int)type & 0xffffff00)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error invalid ephemeral key"); *ret = RHN_ERROR_PARAM; break; } if (bits != bits_priv) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error invalid ephemeral key length"); *ret = RHN_ERROR_PARAM; break; } if (r_jwk_extract_pubkey(jwk_priv, jwk_ephemeral_pub, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error extracting public key from jwk_priv"); *ret = RHN_ERROR; break; } } else { if (r_jwk_init(&jwk_ephemeral) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error r_jwk_init jwk_ephemeral"); *ret = RHN_ERROR; break; } if (r_jwk_generate_key_pair(jwk_ephemeral, jwk_ephemeral_pub, type&R_KEY_TYPE_EC?R_KEY_TYPE_EC:R_KEY_TYPE_ECDH, bits, NULL) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error r_jwk_generate_key_pair"); *ret = RHN_ERROR; break; } r_jwk_delete_property_str(jwk_ephemeral_pub, "kid"); } if (type & R_KEY_TYPE_EC) { if (bits == 256) { nettle_curve = nettle_get_secp_256r1(); crv_size = 32; } else if (bits == 384) { nettle_curve = nettle_get_secp_384r1(); crv_size = 48; } else { nettle_curve = nettle_get_secp_521r1(); crv_size = 64; } if (jwk_priv != NULL) { key = r_jwk_get_property_str(jwk_priv, "d"); } else { key = r_jwk_get_property_str(jwk_ephemeral, "d"); } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode d (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!priv_k_size || priv_k_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Invalid priv_k_size (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), priv_k, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode d (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } key = r_jwk_get_property_str(jwk_pub, "x"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode x (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!pub_x_size || pub_x_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Invalid pub_x_size (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_x, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode x (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } key = r_jwk_get_property_str(jwk_pub, "y"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_y_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode y (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!pub_y_size || pub_y_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Invalid pub_y_size (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_y, &pub_y_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode y (ecdsa)"); *ret = RHN_ERROR_PARAM; break; } if (_r_ecdh_compute(priv_k, priv_k_size, pub_x, pub_x_size, pub_y, pub_y_size, nettle_curve, &Z) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error _r_ecdh_compute (ecdsa)"); *ret = RHN_ERROR; break; } } else { if (bits == 256) { crv_size = CURVE25519_SIZE; curve = GNUTLS_ECC_CURVE_X25519; } else { crv_size = CURVE448_SIZE; curve = GNUTLS_ECC_CURVE_X448; } if (jwk_priv != NULL) { key = r_jwk_get_property_str(jwk_priv, "d"); } else { key = r_jwk_get_property_str(jwk_ephemeral, "d"); } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode d (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!priv_k_size || priv_k_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Invalid priv_k_size (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), priv_k, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode d (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!_r_compare_likely(priv_k_size, (size_t)gnutls_ecc_curve_get_size(curve))) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error invalid priv_k_size (eddsa)"); *ret = RHN_ERROR_PARAM; break; } pub_x_size = CURVE448_SIZE; key = r_jwk_get_property_str(jwk_pub, "x"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode x (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!pub_x_size || pub_x_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Invalid pub_x_size (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_x, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_decode x (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (!_r_compare_likely(pub_x_size, (size_t)gnutls_ecc_curve_get_size(curve))) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error invalid pub_x_size (eddsa)"); *ret = RHN_ERROR_PARAM; break; } if (_r_dh_compute(priv_k, pub_x, crv_size, &Z) != GNUTLS_E_SUCCESS) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error _r_dh_compute (eddsa)"); *ret = RHN_ERROR; break; } } if (_r_concat_kdf(jwe, alg, &Z, &kdf, derived_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error _r_concat_kdf"); *ret = RHN_ERROR; break; } if (alg == R_JWA_ALG_ECDH_ES) { derived_key_len = _r_get_key_size(jwe->enc); } else if (alg == R_JWA_ALG_ECDH_ES_A128KW) { derived_key_len = 16; } else if (alg == R_JWA_ALG_ECDH_ES_A192KW) { derived_key_len = 24; } else if (alg == R_JWA_ALG_ECDH_ES_A256KW) { derived_key_len = 32; } if (alg == R_JWA_ALG_ECDH_ES) { r_jwe_set_cypher_key(jwe, derived_key, derived_key_len); o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; j_return = json_pack("{s{ss so}}", "header", "alg", r_jwa_alg_to_str(alg), "epk", r_jwk_export_to_json_t(jwk_ephemeral_pub)); } else { _r_aes_key_wrap(derived_key, derived_key_len, jwe->key, jwe->key_len, wrapped_key); if (!o_base64url_encode(wrapped_key, jwe->key_len+8, cipherkey_b64url, &cipherkey_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_encrypt - Error o_base64url_encode wrapped_key"); *ret = RHN_ERROR; } o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = (unsigned char *)o_strndup((const char *)cipherkey_b64url, cipherkey_b64url_len); j_return = json_pack("{ss%s{ss so}}", "encrypted_key", cipherkey_b64url, cipherkey_b64url_len, "header", "alg", r_jwa_alg_to_str(alg), "epk", r_jwk_export_to_json_t(jwk_ephemeral_pub)); } } while (0); o_free(kdf.data); gnutls_free(Z.data); r_jwk_free(jwk_ephemeral); r_jwk_free(jwk_ephemeral_pub); return j_return; } static int _r_jwe_ecdh_decrypt(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int type, unsigned int bits, int x5u_flags) { int ret = RHN_OK, key_type = 0; jwk_t * jwk_ephemeral_pub = NULL; json_t * j_epk = NULL; unsigned int epk_bits = 0; gnutls_datum_t Z = {NULL, 0}, kdf = {NULL, 0}; uint8_t derived_key[128] = {0}, key_data[72] = {0}, cipherkey[256] = {0}, priv_k[_R_CURVE_MAX_SIZE] = {0}, pub_x[_R_CURVE_MAX_SIZE] = {0}, pub_y[_R_CURVE_MAX_SIZE] = {0}; size_t derived_key_len = 0, cipherkey_len = 0, priv_k_size = 0, pub_x_size = 0, pub_y_size = 0, crv_size = 0; const char * key = NULL; const struct ecc_curve * nettle_curve; do { if ((j_epk = r_jwe_get_header_json_t_value(jwe, "epk")) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - No epk header"); ret = RHN_ERROR_PARAM; break; } if (r_jwk_init(&jwk_ephemeral_pub) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error r_jwk_init"); ret = RHN_ERROR; break; } if (r_jwk_import_from_json_t(jwk_ephemeral_pub, j_epk) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error r_jwk_import_from_json_t"); ret = RHN_ERROR_PARAM; break; } if (type & R_KEY_TYPE_EC) { key_type = r_jwk_key_type(jwk_ephemeral_pub, &epk_bits, x5u_flags); if (!(key_type & R_KEY_TYPE_EC) || !(key_type & R_KEY_TYPE_PUBLIC) || epk_bits != bits || epk_bits > 384) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error invalid private key type (ecc)"); ret = RHN_ERROR_PARAM; break; } if (bits == 256) { nettle_curve = nettle_get_secp_256r1(); crv_size = 32; } else if (bits == 384) { nettle_curve = nettle_get_secp_384r1(); crv_size = 48; } else { nettle_curve = nettle_get_secp_521r1(); crv_size = 64; } key = r_jwk_get_property_str(jwk, "d"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode d (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!priv_k_size || priv_k_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Invalid priv_k_size (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), priv_k, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode d (ecdsa)"); ret = RHN_ERROR_PARAM; break; } key = r_jwk_get_property_str(jwk_ephemeral_pub, "x"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode x (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!pub_x_size || pub_x_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Invalid pub_x_size (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_x, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode x (ecdsa)"); ret = RHN_ERROR_PARAM; break; } key = r_jwk_get_property_str(jwk_ephemeral_pub, "y"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_y_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode y (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!pub_y_size || pub_y_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Invalid pub_y_size (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_y, &pub_y_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode y (ecdsa)"); ret = RHN_ERROR_PARAM; break; } if (_r_ecdh_compute(priv_k, priv_k_size, pub_x, pub_x_size, pub_y, pub_y_size, nettle_curve, &Z) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error _r_ecdh_compute (ecdsa)"); ret = RHN_ERROR_INVALID; break; } } else { key_type = r_jwk_key_type(jwk_ephemeral_pub, &epk_bits, x5u_flags); if (!(key_type & R_KEY_TYPE_ECDH) || !(key_type & R_KEY_TYPE_PUBLIC) || epk_bits != bits) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error invalid private key type (eddsa)"); ret = RHN_ERROR_INVALID; break; } if (bits == 256) { crv_size = CURVE25519_SIZE; } else { crv_size = CURVE448_SIZE; } key = r_jwk_get_property_str(jwk, "d"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), priv_k, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode d (eddsa)"); ret = RHN_ERROR_PARAM; break; } if (!priv_k_size || priv_k_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Invalid priv_k_size (eddsa)"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &priv_k_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode d (eddsa)"); ret = RHN_ERROR_PARAM; break; } key = r_jwk_get_property_str(jwk_ephemeral_pub, "x"); if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), pub_x, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode x (eddsa)"); ret = RHN_ERROR_PARAM; break; } if (!pub_x_size || pub_x_size > _R_CURVE_MAX_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Invalid priv_k_size (eddsa)"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)key, o_strlen(key), NULL, &pub_x_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode x (eddsa)"); ret = RHN_ERROR_PARAM; break; } if (_r_dh_compute(priv_k, pub_x, crv_size, &Z) != GNUTLS_E_SUCCESS) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error _r_dh_compute (eddsa)"); ret = RHN_ERROR; break; } } if (_r_concat_kdf(jwe, alg, &Z, &kdf, derived_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error _r_concat_kdf"); ret = RHN_ERROR; break; } if (alg == R_JWA_ALG_ECDH_ES) { derived_key_len = _r_get_key_size(jwe->enc); } else if (alg == R_JWA_ALG_ECDH_ES_A128KW) { derived_key_len = 16; } else if (alg == R_JWA_ALG_ECDH_ES_A192KW) { derived_key_len = 24; } else if (alg == R_JWA_ALG_ECDH_ES_A256KW) { derived_key_len = 32; } if (alg == R_JWA_ALG_ECDH_ES) { r_jwe_set_cypher_key(jwe, derived_key, derived_key_len); } else { if (o_base64url_decode(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), cipherkey, &cipherkey_len)) { if (_r_aes_key_unwrap(derived_key, derived_key_len, key_data, cipherkey_len-8, cipherkey)) { r_jwe_set_cypher_key(jwe, key_data, cipherkey_len-8); } else { ret = RHN_ERROR_INVALID; break; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_jwe_ecdh_decrypt - Error o_base64url_decode cipherkey"); ret = RHN_ERROR; break; } } } while (0); o_free(kdf.data); gnutls_free(Z.data); r_jwk_free(jwk_ephemeral_pub); json_decref(j_epk); return ret; } #endif // PBES2 #if GNUTLS_VERSION_NUMBER >= 0x03060d static json_t * r_jwe_pbes2_key_wrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags, int * ret) { unsigned char salt_seed[_R_PBES_DEFAULT_SALT_LENGTH] = {0}, salt_seed_b64[_R_PBES_DEFAULT_SALT_LENGTH*2], * salt = NULL, kek[64] = {0}, * key = NULL, wrapped_key[72] = {0}, cipherkey_b64url[256] = {0}; size_t alg_len, salt_len, key_len = 0, cipherkey_b64url_len = 0, salt_seed_b64_len = 0, kek_len = 0; const char * p2s = NULL; unsigned int p2c = 0, bits = 0; gnutls_datum_t password = {NULL, 0}, g_salt = {NULL, 0}; gnutls_mac_algorithm_t mac = GNUTLS_MAC_UNKNOWN; json_t * j_return = NULL, * j_p2s = NULL, * j_p2c = NULL; struct _o_datum dat_dec = {0, NULL}; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { do { alg_len = o_strlen(r_jwa_alg_to_str(alg)); j_p2s = r_jwe_get_header_json_t_value(jwe, "p2s"); if (j_p2s != NULL) { if (!json_is_string(j_p2s) || !json_string_length(j_p2s)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error p2s type"); *ret = RHN_ERROR_PARAM; break; } } if ((p2s = r_jwe_get_header_str_value(jwe, "p2s")) != NULL) { if (!o_base64url_decode_alloc((const unsigned char *)p2s, o_strlen(p2s), &dat_dec)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error o_base64url_decode_alloc p2s"); *ret = RHN_ERROR_PARAM; break; } if (dat_dec.size < 8) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error invalid p2s length"); *ret = RHN_ERROR_PARAM; break; } salt_len = dat_dec.size + alg_len + 1; if ((salt = o_malloc(salt_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error o_malloc salt (1)"); *ret = RHN_ERROR_MEMORY; break; } memcpy(salt, r_jwa_alg_to_str(alg), alg_len); memset(salt+alg_len, 0, 1); memcpy(salt+alg_len+1, dat_dec.data, dat_dec.size); } else { if (gnutls_rnd(GNUTLS_RND_NONCE, salt_seed, _R_PBES_DEFAULT_SALT_LENGTH)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error gnutls_rnd"); *ret = RHN_ERROR; break; } salt_len = _R_PBES_DEFAULT_SALT_LENGTH + alg_len + 1; if ((salt = o_malloc(salt_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error o_malloc salt (2)"); *ret = RHN_ERROR_MEMORY; break; } if (!o_base64url_encode(salt_seed, _R_PBES_DEFAULT_SALT_LENGTH, salt_seed_b64, &salt_seed_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error o_base64url_encode salt_seed"); *ret = RHN_ERROR; break; } salt_seed_b64[salt_seed_b64_len] = '\0'; memcpy(salt, r_jwa_alg_to_str(alg), alg_len); memset(salt+alg_len, 0, 1); memcpy(salt+alg_len+1, salt_seed, _R_PBES_DEFAULT_SALT_LENGTH); } j_p2c = r_jwe_get_header_json_t_value(jwe, "p2c"); if (j_p2c != NULL) { if (!json_is_integer(j_p2c) || json_integer_value(j_p2c) <= 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error p2c"); *ret = RHN_ERROR_PARAM; break; } } if ((p2c = (unsigned int)r_jwe_get_header_int_value(jwe, "p2c")) <= 0) { p2c = _R_PBES_DEFAULT_ITERATION; } key_len = (bits/8)+4; if ((key = o_malloc(key_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error o_malloc key"); *ret = RHN_ERROR_MEMORY; break; } if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error r_jwk_export_to_symmetric_key"); *ret = RHN_ERROR; break; } password.data = key; password.size = (unsigned int)key_len; g_salt.data = salt; g_salt.size = (unsigned int)salt_len; if (alg == R_JWA_ALG_PBES2_H256) { kek_len = 16; mac = GNUTLS_MAC_SHA256; } else if (alg == R_JWA_ALG_PBES2_H384) { kek_len = 24; mac = GNUTLS_MAC_SHA384; } else if (alg == R_JWA_ALG_PBES2_H512) { kek_len = 32; mac = GNUTLS_MAC_SHA512; } if (gnutls_pbkdf2(mac, &password, &g_salt, p2c, kek, kek_len) != GNUTLS_E_SUCCESS) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error gnutls_pbkdf2"); *ret = RHN_ERROR; break; } _r_aes_key_wrap(kek, kek_len, jwe->key, jwe->key_len, wrapped_key); if (!o_base64url_encode(wrapped_key, jwe->key_len+8, cipherkey_b64url, &cipherkey_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aes_key_wrap - Error o_base64url_encode wrapped_key"); *ret = RHN_ERROR; break; } j_return = json_pack("{ss%s{sssssi}}", "encrypted_key", cipherkey_b64url, cipherkey_b64url_len, "header", "alg", r_jwa_alg_to_str(alg), "p2s", p2s!=NULL?p2s:(const char*)salt_seed_b64, "p2c", p2c); } while (0); o_free(key); o_free(salt); o_free(dat_dec.data); json_decref(j_p2s); json_decref(j_p2c); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_wrap - Error invalid key"); } return j_return; } static int r_jwe_pbes2_key_unwrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags) { unsigned char * salt = NULL, kek[64] = {0}, * key = NULL, cipherkey[128] = {0}, key_data[64] = {0}; size_t alg_len, salt_len, key_len = 0, cipherkey_len = 0, kek_len = 0; int ret; const char * p2s; unsigned int p2c, bits = 0; gnutls_datum_t password = {NULL, 0}, g_salt = {NULL, 0}; gnutls_mac_algorithm_t mac = GNUTLS_MAC_UNKNOWN; struct _o_datum dat_dec = {0, NULL}; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { ret = RHN_OK; do { alg_len = o_strlen(r_jwe_get_header_str_value(jwe, "alg")); if ((p2c = (unsigned int)r_jwe_get_header_int_value(jwe, "p2c")) <= 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error invalid p2c"); ret = RHN_ERROR_PARAM; break; } if (!o_strlen(r_jwe_get_header_str_value(jwe, "p2s"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error invalid p2s"); ret = RHN_ERROR_PARAM; break; } p2s = r_jwe_get_header_str_value(jwe, "p2s"); if (!o_base64url_decode_alloc((const unsigned char *)p2s, o_strlen(p2s), &dat_dec)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error o_base64url_decode_alloc p2s"); ret = RHN_ERROR_PARAM; break; } if (dat_dec.size < 8) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error invalid p2s size"); ret = RHN_ERROR_PARAM; break; } salt_len = dat_dec.size + alg_len + 1; if ((salt = o_malloc(salt_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error o_malloc salt"); ret = RHN_ERROR_MEMORY; break; } memcpy(salt, r_jwe_get_header_str_value(jwe, "alg"), alg_len); memset(salt+alg_len, 0, 1); memcpy(salt+alg_len+1, dat_dec.data, dat_dec.size); key_len = (bits/8)+4; if ((key = o_malloc(key_len)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error o_malloc key"); ret = RHN_ERROR_MEMORY; break; } if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error r_jwk_export_to_symmetric_key"); ret = RHN_ERROR; break; } password.data = key; password.size = (unsigned int)key_len; g_salt.data = salt; g_salt.size = (unsigned int)salt_len; if (alg == R_JWA_ALG_PBES2_H256) { kek_len = 16; mac = GNUTLS_MAC_SHA256; } else if (alg == R_JWA_ALG_PBES2_H384) { kek_len = 24; mac = GNUTLS_MAC_SHA384; } else if (alg == R_JWA_ALG_PBES2_H512) { kek_len = 32; mac = GNUTLS_MAC_SHA512; } if (gnutls_pbkdf2(mac, &password, &g_salt, p2c, kek, kek_len) != GNUTLS_E_SUCCESS) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error gnutls_pbkdf2"); ret = RHN_ERROR; break; } if (!o_base64url_decode(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), cipherkey, &cipherkey_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error o_base64url_decode cipherkey"); ret = RHN_ERROR; break; } if (!_r_aes_key_unwrap(kek, kek_len, key_data, cipherkey_len-8, cipherkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error _r_aes_key_unwrap"); ret = RHN_ERROR_INVALID; break; } if (r_jwe_set_cypher_key(jwe, key_data, cipherkey_len-8) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error r_jwe_set_cypher_key"); ret = RHN_ERROR; } } while (0); o_free(key); o_free(salt); o_free(dat_dec.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_pbes2_key_unwrap - Error invalid key"); ret = RHN_ERROR_PARAM; } return ret; } #endif static gnutls_mac_algorithm_t r_jwe_get_digest_from_enc(jwa_enc enc) { gnutls_mac_algorithm_t digest; switch (enc) { case R_JWA_ENC_A128CBC: digest = GNUTLS_MAC_SHA256; break; case R_JWA_ENC_A192CBC: digest = GNUTLS_MAC_SHA384; break; case R_JWA_ENC_A256CBC: digest = GNUTLS_MAC_SHA512; break; case R_JWA_ENC_A128GCM: digest = GNUTLS_MAC_SHA256; break; case R_JWA_ENC_A192GCM: digest = GNUTLS_MAC_SHA384; break; case R_JWA_ENC_A256GCM: digest = GNUTLS_MAC_SHA512; break; default: digest = GNUTLS_MAC_UNKNOWN; break; } return digest; } static gnutls_cipher_algorithm_t r_jwe_get_alg_from_alg(jwa_alg alg) { gnutls_cipher_algorithm_t ret_alg = GNUTLS_CIPHER_UNKNOWN; switch (alg) { case R_JWA_ALG_A128GCMKW: ret_alg = GNUTLS_CIPHER_AES_128_GCM; break; case R_JWA_ALG_A192GCMKW: #if GNUTLS_VERSION_NUMBER >= 0x03060e ret_alg = GNUTLS_CIPHER_AES_192_GCM; #else ret_alg = GNUTLS_CIPHER_UNKNOWN; // Unsupported until GnuTLS 3.6.14 #endif break; case R_JWA_ALG_A256GCMKW: ret_alg = GNUTLS_CIPHER_AES_256_GCM; break; default: ret_alg = GNUTLS_CIPHER_UNKNOWN; break; } return ret_alg; } static json_t * r_jwe_aesgcm_key_wrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags, int * ret) { int res; unsigned char iv[96] = {0}, * key = NULL, cipherkey[64] = {0}, cipherkey_b64url[128] = {0}, tag[128] = {0}, tag_b64url[256] = {0}; size_t key_len = 0, cipherkey_b64url_len = 0, tag_b64url_len = 0, iv_size = (unsigned)gnutls_cipher_get_iv_size(r_jwe_get_alg_from_alg(alg)), tag_len = (unsigned)gnutls_cipher_get_tag_size(r_jwe_get_alg_from_alg(alg)); unsigned int bits = 0; gnutls_datum_t key_g, iv_g; gnutls_cipher_hd_t handle = NULL; json_t * j_return = NULL, * j_iv = NULL; struct _o_datum dat_iv_enc = {0, NULL}, dat_iv_dec = {0, NULL}; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { key_len = bits; do { if ((key = o_malloc(key_len+4)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error allocating resources for key"); *ret = RHN_ERROR_MEMORY; break; } if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error r_jwk_export_to_symmetric_key"); *ret = RHN_ERROR_PARAM; break; } j_iv = r_jwe_get_header_json_t_value(jwe, "iv"); if (j_iv != NULL) { if (!json_is_string(j_iv) || !json_string_length(j_iv)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error invalid iv"); *ret = RHN_ERROR; break; } } if (r_jwe_get_header_str_value(jwe, "iv") == NULL) { if (gnutls_rnd(GNUTLS_RND_NONCE, iv, iv_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error gnutls_rnd"); *ret = RHN_ERROR; break; } if (!o_base64url_encode_alloc(iv, iv_size, &dat_iv_enc)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error o_base64url_encode_alloc iv"); *ret = RHN_ERROR; break; } } else { if (!o_base64url_decode_alloc((const unsigned char *)r_jwe_get_header_str_value(jwe, "iv"), o_strlen(r_jwe_get_header_str_value(jwe, "iv")), &dat_iv_dec)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error o_base64url_decode iv"); *ret = RHN_ERROR_PARAM; break; } if (dat_iv_dec.size != iv_size) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error invalid iv size in header"); *ret = RHN_ERROR_PARAM; break; } memcpy(iv, dat_iv_dec.data, dat_iv_dec.size); if (iv_size != (unsigned)gnutls_cipher_get_iv_size(r_jwe_get_alg_from_alg(alg))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error invalid iv size"); *ret = RHN_ERROR_PARAM; break; } } key_g.data = key; key_g.size = (unsigned int)key_len; iv_g.data = iv; iv_g.size = (unsigned int)iv_size; if ((res = gnutls_cipher_init(&handle, r_jwe_get_alg_from_alg(alg), &key_g, &iv_g))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error gnutls_cipher_init: '%s'", gnutls_strerror(res)); y_log_message(Y_LOG_LEVEL_DEBUG, "%zu - %zu", key_g.size, iv_g.size); *ret = RHN_ERROR_PARAM; break; } if ((res = gnutls_cipher_encrypt2(handle, jwe->key, jwe->key_len, cipherkey, jwe->key_len))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error gnutls_cipher_encrypt2: '%s'", gnutls_strerror(res)); *ret = RHN_ERROR; break; } if (!o_base64url_encode(cipherkey, jwe->key_len, cipherkey_b64url, &cipherkey_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error o_base64url_encode cipherkey"); *ret = RHN_ERROR; break; } if ((res = gnutls_cipher_tag(handle, tag, tag_len))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error gnutls_cipher_tag: '%s'", gnutls_strerror(res)); *ret = RHN_ERROR; break; } if (!o_base64url_encode(tag, tag_len, tag_b64url, &tag_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error o_base64url_encode tag"); *ret = RHN_ERROR; break; } tag_b64url[tag_b64url_len] = '\0'; j_return = json_pack("{ss%s{ssss}}", "encrypted_key", cipherkey_b64url, cipherkey_b64url_len, "header", "tag", tag_b64url, "alg", r_jwa_alg_to_str(alg)); if (r_jwe_get_header_str_value(jwe, "iv") == NULL) { json_object_set_new(json_object_get(j_return, "header"), "iv", json_stringn((const char *)dat_iv_enc.data, dat_iv_enc.size)); } else { json_object_set_new(json_object_get(j_return, "header"), "iv", json_string(r_jwe_get_header_str_value(jwe, "iv"))); } } while (0); o_free(key); o_free(dat_iv_enc.data); o_free(dat_iv_dec.data); json_decref(j_iv); if (handle != NULL) { gnutls_cipher_deinit(handle); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_wrap - Error invalid key"); *ret = RHN_ERROR_PARAM; } return j_return; } static int r_jwe_set_alg_header(jwe_t * jwe, json_t * j_header) { int ret = RHN_OK; switch (jwe->alg) { case R_JWA_ALG_NONE: json_object_set_new(j_header, "alg", json_string("none")); break; case R_JWA_ALG_RSA1_5: json_object_set_new(j_header, "alg", json_string("RSA1_5")); break; case R_JWA_ALG_RSA_OAEP: json_object_set_new(j_header, "alg", json_string("RSA-OAEP")); break; case R_JWA_ALG_RSA_OAEP_256: json_object_set_new(j_header, "alg", json_string("RSA-OAEP-256")); break; case R_JWA_ALG_A128KW: json_object_set_new(j_header, "alg", json_string("A128KW")); break; case R_JWA_ALG_A192KW: json_object_set_new(j_header, "alg", json_string("A192KW")); break; case R_JWA_ALG_A256KW: json_object_set_new(j_header, "alg", json_string("A256KW")); break; case R_JWA_ALG_DIR: json_object_set_new(j_header, "alg", json_string("dir")); break; case R_JWA_ALG_ECDH_ES: json_object_set_new(j_header, "alg", json_string("ECDH-ES")); break; case R_JWA_ALG_ECDH_ES_A128KW: json_object_set_new(j_header, "alg", json_string("ECDH-ES+A128KW")); break; case R_JWA_ALG_ECDH_ES_A192KW: json_object_set_new(j_header, "alg", json_string("ECDH-ES+A192KW")); break; case R_JWA_ALG_ECDH_ES_A256KW: json_object_set_new(j_header, "alg", json_string("ECDH-ES+A256KW")); break; case R_JWA_ALG_A128GCMKW: json_object_set_new(j_header, "alg", json_string("A128GCMKW")); break; case R_JWA_ALG_A192GCMKW: json_object_set_new(j_header, "alg", json_string("A192GCMKW")); break; case R_JWA_ALG_A256GCMKW: json_object_set_new(j_header, "alg", json_string("A256GCMKW")); break; case R_JWA_ALG_PBES2_H256: json_object_set_new(j_header, "alg", json_string("PBES2-HS256+A128KW")); break; case R_JWA_ALG_PBES2_H384: json_object_set_new(j_header, "alg", json_string("PBES2-HS384+A192KW")); break; case R_JWA_ALG_PBES2_H512: json_object_set_new(j_header, "alg", json_string("PBES2-HS512+A256KW")); break; default: ret = RHN_ERROR_PARAM; break; } return ret; } static int r_jwe_set_enc_header(jwe_t * jwe, json_t * j_header) { int ret = RHN_OK; switch (jwe->enc) { case R_JWA_ENC_A128CBC: json_object_set_new(j_header, "enc", json_string("A128CBC-HS256")); break; case R_JWA_ENC_A192CBC: json_object_set_new(j_header, "enc", json_string("A192CBC-HS384")); break; case R_JWA_ENC_A256CBC: json_object_set_new(j_header, "enc", json_string("A256CBC-HS512")); break; case R_JWA_ENC_A128GCM: json_object_set_new(j_header, "enc", json_string("A128GCM")); break; case R_JWA_ENC_A192GCM: json_object_set_new(j_header, "enc", json_string("A192GCM")); break; case R_JWA_ENC_A256GCM: json_object_set_new(j_header, "enc", json_string("A256GCM")); break; default: ret = RHN_ERROR_PARAM; break; } return ret; } static int r_jwe_aesgcm_key_unwrap(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags) { int ret, res; unsigned char * key = NULL, tag[128] = {0}, tag_b64url[256] = {0}; size_t key_len = 0, tag_b64url_len = 0, tag_len = (unsigned)gnutls_cipher_get_tag_size(r_jwe_get_alg_from_alg(alg)); unsigned int bits = 0; gnutls_datum_t key_g, iv_g; gnutls_cipher_hd_t handle = NULL; struct _o_datum dat_iv = {0, NULL}, dat_key = {0, NULL}; if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC && !o_strnullempty(r_jwe_get_header_str_value(jwe, "iv")) && !o_strnullempty(r_jwe_get_header_str_value(jwe, "tag"))) { ret = RHN_OK; key_len = bits; do { if ((key = o_malloc(key_len+4)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; break; } if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error r_jwk_export_to_symmetric_key"); ret = RHN_ERROR; break; } if (!o_base64url_decode_alloc((const unsigned char *)r_jwe_get_header_str_value(jwe, "iv"), o_strlen(r_jwe_get_header_str_value(jwe, "iv")), &dat_iv)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error o_base64url_decode iv"); ret = RHN_ERROR_INVALID; break; } if (dat_iv.size != 12) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error invalid iv"); ret = RHN_ERROR_INVALID; break; } if (!o_base64url_decode_alloc((const unsigned char *)jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), &dat_key)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error o_base64url_decode cipherkey"); ret = RHN_ERROR_INVALID; break; } key_g.data = key; key_g.size = (unsigned int)key_len; iv_g.data = dat_iv.data; iv_g.size = (unsigned int)dat_iv.size; if ((res = gnutls_cipher_init(&handle, r_jwe_get_alg_from_alg(alg), &key_g, &iv_g))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error gnutls_cipher_init: '%s'", gnutls_strerror(res)); ret = RHN_ERROR_INVALID; break; } if ((res = gnutls_cipher_decrypt(handle, dat_key.data, dat_key.size))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error gnutls_cipher_decrypt: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; break; } if ((res = gnutls_cipher_tag(handle, tag, tag_len))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error gnutls_cipher_tag: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; break; } if (!o_base64url_encode(tag, tag_len, tag_b64url, &tag_b64url_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error o_base64url_encode tag"); ret = RHN_ERROR; break; } tag_b64url[tag_b64url_len] = '\0'; if (0 != o_strcmp((const char *)tag_b64url, r_jwe_get_header_str_value(jwe, "tag"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Invalid tag %s %s", tag_b64url, r_jwe_get_header_str_value(jwe, "tag")); ret = RHN_ERROR_INVALID; break; } if (r_jwe_set_cypher_key(jwe, dat_key.data, dat_key.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error r_jwe_set_cypher_key"); ret = RHN_ERROR; } } while (0); o_free(key); o_free(dat_key.data); o_free(dat_iv.data); if (handle != NULL) { gnutls_cipher_deinit(handle); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_aesgcm_key_unwrap - Error invalid key"); ret = RHN_ERROR_INVALID; } return ret; } static int r_jwe_set_ptext_with_block(unsigned char * data, size_t data_len, unsigned char ** ptext, size_t * ptext_len, gnutls_cipher_algorithm_t alg, int cipher_cbc) { size_t b_size = (size_t)gnutls_cipher_get_block_size(alg); int ret; *ptext = NULL; if (cipher_cbc) { if (data_len % b_size) { *ptext_len = ((data_len/b_size)+1)*b_size; } else { *ptext_len = data_len; } if (*ptext_len) { if ((*ptext = o_malloc(*ptext_len)) != NULL) { memcpy(*ptext, data, data_len); memset(*ptext+data_len, (int)((*ptext_len)-data_len), (*ptext_len)-data_len); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_ptext_with_block - Error allocating resources for ptext (1)"); ret = RHN_ERROR_MEMORY; } } else { ret = RHN_ERROR; } } else { *ptext_len = data_len; if ((*ptext = o_malloc(data_len)) != NULL) { memcpy(*ptext, data, data_len); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_ptext_with_block - Error allocating resources for ptext (2)"); ret = RHN_ERROR_MEMORY; } } return ret; } static int r_jwe_extract_header(jwe_t * jwe, json_t * j_header, uint32_t parse_flags, int x5u_flags) { int ret, key_type; jwk_t * jwk; const char * apu = NULL, * apv = NULL, * iv = NULL, * tag = NULL, * p2s = NULL; size_t apu_size = 0, apv_size = 0, iv_size = 0, tag_size = 0, p2s_size = 0; json_int_t p2c = 0; if (json_is_object(j_header)) { ret = RHN_OK; if (json_object_get(j_header, "alg") != NULL) { if (0 != o_strcmp("RSA1_5", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("RSA-OAEP", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("RSA-OAEP-256", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A128KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A192KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A256KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("dir", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ECDH-ES", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ECDH-ES+A128KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ECDH-ES+A192KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ECDH-ES+A256KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A128GCMKW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A192GCMKW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("A256GCMKW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PBES2-HS256+A128KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PBES2-HS384+A192KW", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PBES2-HS512+A256KW", json_string_value(json_object_get(j_header, "alg")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Invalid alg"); ret = RHN_ERROR_PARAM; } else { jwe->alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg"))); } } if (json_object_get(j_header, "enc") != NULL) { if (0 != o_strcmp("A128CBC-HS256", json_string_value(json_object_get(j_header, "enc"))) && 0 != o_strcmp("A192CBC-HS384", json_string_value(json_object_get(j_header, "enc"))) && 0 != o_strcmp("A256CBC-HS512", json_string_value(json_object_get(j_header, "enc"))) && 0 != o_strcmp("A128GCM", json_string_value(json_object_get(j_header, "enc"))) && 0 != o_strcmp("A192GCM", json_string_value(json_object_get(j_header, "enc"))) && 0 != o_strcmp("A256GCM", json_string_value(json_object_get(j_header, "enc")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Invalid enc"); ret = RHN_ERROR_PARAM; } else { jwe->enc = r_str_to_jwa_enc(json_string_value(json_object_get(j_header, "enc"))); } } if (json_string_length(json_object_get(j_header, "jku")) && (parse_flags&R_PARSE_HEADER_JKU)) { if (r_jwks_import_from_uri(jwe->jwks_pubkey, json_string_value(json_object_get(j_header, "jku")), x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error loading jwks from uri %s", json_string_value(json_object_get(j_header, "jku"))); } } if (json_object_get(j_header, "jwk") != NULL && (parse_flags&R_PARSE_HEADER_JWK)) { r_jwk_init(&jwk); if (r_jwk_import_from_json_t(jwk, json_object_get(j_header, "jwk")) == RHN_OK && r_jwk_key_type(jwk, NULL, 0)&R_KEY_TYPE_PUBLIC) { if (r_jwks_append_jwk(jwe->jwks_pubkey, jwk) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error parsing header jwk"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } if (json_object_get(j_header, "x5u") != NULL && (parse_flags&R_PARSE_HEADER_X5U)) { r_jwk_init(&jwk); if (r_jwk_import_from_x5u(jwk, x5u_flags, json_string_value(json_object_get(j_header, "x5u"))) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, jwk) != RHN_OK) { ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error importing x5u"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } if (json_object_get(j_header, "x5c") != NULL && (parse_flags&R_PARSE_HEADER_X5C)) { r_jwk_init(&jwk); if (r_jwk_import_from_x5c(jwk, json_string_value(json_array_get(json_object_get(j_header, "x5c"), 0))) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, jwk) != RHN_OK) { ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error importing x5c"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } if (jwe->alg == R_JWA_ALG_ECDH_ES || jwe->alg == R_JWA_ALG_ECDH_ES_A128KW || jwe->alg == R_JWA_ALG_ECDH_ES_A192KW || jwe->alg == R_JWA_ALG_ECDH_ES_A256KW) { if (json_object_get(j_header, "epk") == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - No epk header"); ret = RHN_ERROR_PARAM; } r_jwk_init(&jwk); if (r_jwk_import_from_json_t(jwk, json_object_get(j_header, "epk")) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error header epk invalid"); ret = RHN_ERROR_PARAM; } key_type = r_jwk_key_type(jwk, NULL, 0); if (!(key_type & R_KEY_TYPE_PUBLIC) || !(key_type&(R_KEY_TYPE_EC|R_KEY_TYPE_ECDH))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error header epk invalid type"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); if (json_object_get(j_header, "apu") != NULL) { if (!json_is_string(json_object_get(j_header, "apu"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid apu"); ret = RHN_ERROR_PARAM; } else { apu = json_string_value(json_object_get(j_header, "apu")); if (!o_strnullempty(apu)) { if (!o_base64url_decode((const unsigned char *)apu, o_strlen(apu), NULL, &apu_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error o_base64url_decode_alloc apu"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid apu size"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(j_header, "apv") != NULL) { if (!json_is_string(json_object_get(j_header, "apv"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid apv"); ret = RHN_ERROR_PARAM; } else { apv = json_string_value(json_object_get(j_header, "apv")); if (!o_strnullempty(apv)) { if (!o_base64url_decode((const unsigned char *)apv, o_strlen(apv), NULL, &apv_size)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error o_base64url_decode apv"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid apv size"); ret = RHN_ERROR_PARAM; } } } } if (jwe->alg == R_JWA_ALG_A128GCMKW || jwe->alg == R_JWA_ALG_A192GCMKW || jwe->alg == R_JWA_ALG_A256GCMKW) { if (!json_is_string(json_object_get(j_header, "iv"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid iv"); ret = RHN_ERROR_PARAM; } else { iv = json_string_value(json_object_get(j_header, "iv")); if (!o_strnullempty(iv)) { if (!o_base64url_decode((const unsigned char *)iv, o_strlen(iv), NULL, &iv_size) || iv_size != 12) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error o_base64url_decode iv"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid iv size"); ret = RHN_ERROR_PARAM; } } if (!json_is_string(json_object_get(j_header, "tag"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid tag"); ret = RHN_ERROR_PARAM; } else { tag = json_string_value(json_object_get(j_header, "tag")); if (!o_strnullempty(tag)) { if (!o_base64url_decode((const unsigned char *)tag, o_strlen(tag), NULL, &tag_size) || tag_size != 16) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error o_base64url_decode tag %zu", tag_size); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid tag size"); ret = RHN_ERROR_PARAM; } } } if (jwe->alg == R_JWA_ALG_PBES2_H256 || jwe->alg == R_JWA_ALG_PBES2_H384 || jwe->alg == R_JWA_ALG_PBES2_H512) { if (!json_is_string(json_object_get(j_header, "p2s"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid p2s"); ret = RHN_ERROR_PARAM; } else { p2s = json_string_value(json_object_get(j_header, "p2s")); if (!o_strnullempty(p2s)) { if (!o_base64url_decode((const unsigned char *)p2s, o_strlen(p2s), NULL, &p2s_size) || p2s_size < 8) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error o_base64url_decode p2s"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid p2s size"); ret = RHN_ERROR_PARAM; } } if (!json_is_integer(json_object_get(j_header, "p2c"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid p2c"); ret = RHN_ERROR_PARAM; } else { p2c = json_integer_value(json_object_get(j_header, "p2c")); if (p2c <= 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_extract_header - Error invalid p2c value"); ret = RHN_ERROR_PARAM; } } } } else { ret = RHN_ERROR_PARAM; } return ret; } static void r_jwe_remove_padding(unsigned char * text, size_t * text_len, unsigned int block_size) { unsigned char pad = text[(*text_len)-1], i; int pad_ok = 1; if (pad && pad < (unsigned char)block_size) { for (i=0; ienc); aad_len = (uint64_t)(o_strlen((const char *)aad)*8); memset(al, 0, 8); for(i = 0; i < 8; i++) { al[i] = (uint8_t)((aad_len >> 8*(7 - i)) & 0xFF); } if ((compute_hmac = o_malloc(aad_size+jwe->iv_len+cyphertext_len+8)) != NULL) { if (aad_size) { memcpy(compute_hmac, aad, aad_size); hmac_size += aad_size; } memcpy(compute_hmac+hmac_size, jwe->iv, jwe->iv_len); hmac_size += jwe->iv_len; memcpy(compute_hmac+hmac_size, ciphertext, cyphertext_len); hmac_size += cyphertext_len; memcpy(compute_hmac+hmac_size, al, 8); hmac_size += 8; if (!(res = gnutls_hmac_fast(mac, jwe->key, jwe->key_len/2, compute_hmac, hmac_size, tag))) { *tag_len = (unsigned)gnutls_hmac_get_len(mac)/2; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_compute_hmac_tag - Error gnutls_hmac_fast: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } o_free(compute_hmac); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_compute_hmac_tag - Error allocating resources for compute_hmac"); ret = RHN_ERROR; } return ret; } static json_t * r_jwe_perform_key_encryption(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags, int * ret) { json_t * j_return = NULL; int res; unsigned int bits = 0; gnutls_pubkey_t g_pub = NULL; gnutls_datum_t plainkey, cypherkey = {NULL, 0}; unsigned char key[128] = {0}; size_t key_len = 0, index = 0; const char * key_ref = NULL; json_t * j_element = NULL, * j_reference, * j_key_ref_array; struct _o_datum dat = {0, NULL}; #if NETTLE_VERSION_NUMBER >= 0x030400 uint8_t * cyphertext = NULL; size_t cyphertext_len = 0; #endif #if NETTLE_VERSION_NUMBER >= 0x030600 json_t * jwk_priv = NULL; unsigned int bits_priv = 0; int res_priv; #endif switch (alg) { case R_JWA_ALG_RSA1_5: res = r_jwk_key_type(jwk, &bits, x5u_flags); if (res & R_KEY_TYPE_RSA && bits >= 2048) { if (jwk != NULL && (g_pub = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags)) != NULL) { plainkey.data = jwe->key; plainkey.size = (unsigned int)jwe->key_len; if (!(res = gnutls_pubkey_encrypt_data(g_pub, 0, &plainkey, &cypherkey))) { if (o_base64url_encode_alloc(cypherkey.data, cypherkey.size, &dat)) { j_return = json_pack("{ss%s{ss}}", "encrypted_key", dat.data, dat.size, "header", "alg", r_jwa_alg_to_str(alg)); o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error o_base64url_encode cypherkey_b64"); *ret = RHN_ERROR; } gnutls_free(cypherkey.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error gnutls_pubkey_encrypt_data: %s", gnutls_strerror(res)); *ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Unable to export public key"); *ret = RHN_ERROR; } gnutls_pubkey_deinit(g_pub); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error invalid key type (rsa)"); *ret = RHN_ERROR_PARAM; } break; #if NETTLE_VERSION_NUMBER >= 0x030400 case R_JWA_ALG_RSA_OAEP: case R_JWA_ALG_RSA_OAEP_256: res = r_jwk_key_type(jwk, &bits, x5u_flags); if (res & R_KEY_TYPE_RSA && bits >= 2048) { if (jwk != NULL && (g_pub = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags)) != NULL) { if ((cyphertext = o_malloc(bits+1)) != NULL) { cyphertext_len = bits+1; if (_r_rsa_oaep_encrypt(g_pub, alg, jwe->key, jwe->key_len, cyphertext, &cyphertext_len) == RHN_OK) { if (o_base64url_encode_alloc(cyphertext, cyphertext_len, &dat)) { j_return = json_pack("{ss%s{ss}}", "encrypted_key", dat.data, dat.size, "header", "alg", r_jwa_alg_to_str(alg)); o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error o_base64url_encode cypherkey_b64"); *ret = RHN_ERROR; } gnutls_free(cypherkey.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error _r_rsa_oaep_encrypt"); *ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error allocating resources for cyphertext"); *ret = RHN_ERROR_MEMORY; } o_free(cyphertext); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Unable to export public key"); *ret = RHN_ERROR; } gnutls_pubkey_deinit(g_pub); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error invalid key type (rsa oaep)"); *ret = RHN_ERROR_PARAM; } break; #endif case R_JWA_ALG_DIR: o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; if (jwk != NULL) { if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC && bits == _r_get_key_size(jwe->enc)*8) { key_len = bits/8; if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error r_jwk_export_to_symmetric_key"); *ret = RHN_ERROR; } else { if (r_jwe_set_cypher_key(jwe, key, key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error r_jwe_set_cypher_key"); *ret = RHN_ERROR; } else { j_return = json_object(); } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error invalid key type (dir)"); *ret = RHN_ERROR_PARAM; } } else if (jwe->key != NULL && jwe->key_len > 0) { j_return = json_object(); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error no key available for alg 'dir'"); *ret = RHN_ERROR_PARAM; } break; case R_JWA_ALG_A128GCMKW: #if GNUTLS_VERSION_NUMBER >= 0x03060e case R_JWA_ALG_A192GCMKW: #endif case R_JWA_ALG_A256GCMKW: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { if ((j_return = r_jwe_aesgcm_key_wrap(jwe, alg, jwk, x5u_flags, ret)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error r_jwe_aesgcm_key_wrap"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error invalid key type (AES-GCM)"); *ret = RHN_ERROR_PARAM; } break; #if NETTLE_VERSION_NUMBER >= 0x030400 case R_JWA_ALG_A128KW: case R_JWA_ALG_A192KW: case R_JWA_ALG_A256KW: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { if ((j_return = r_jwe_aes_key_wrap(jwe, alg, jwk, x5u_flags, ret)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error r_jwe_aes_key_wrap"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error invalid key type (AES KeyWrap)"); *ret = RHN_ERROR_PARAM; } break; #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d case R_JWA_ALG_PBES2_H256: case R_JWA_ALG_PBES2_H384: case R_JWA_ALG_PBES2_H512: if ((j_return = r_jwe_pbes2_key_wrap(jwe, alg, jwk, x5u_flags, ret)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error r_jwe_pbes2_key_wrap"); } break; #endif #if NETTLE_VERSION_NUMBER >= 0x030600 case R_JWA_ALG_ECDH_ES: case R_JWA_ALG_ECDH_ES_A128KW: case R_JWA_ALG_ECDH_ES_A192KW: case R_JWA_ALG_ECDH_ES_A256KW: res = r_jwk_key_type(jwk, &bits, x5u_flags); if ((res & R_KEY_TYPE_ECDH || res & R_KEY_TYPE_EC) && res & R_KEY_TYPE_PUBLIC && bits < 521) { *ret = RHN_OK; if (r_jwks_size(jwe->jwks_privkey) == 1) { jwk_priv = r_jwks_get_at(jwe->jwks_privkey, 0); res_priv = r_jwk_key_type(jwk_priv, &bits_priv, x5u_flags); if (!(res_priv & R_KEY_TYPE_PRIVATE) || (res & R_KEY_TYPE_ECDH && !(res_priv & R_KEY_TYPE_ECDH)) || (res & R_KEY_TYPE_EC && !(res_priv & R_KEY_TYPE_EC)) || bits != bits_priv) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - invalid private key"); *ret = RHN_ERROR_PARAM; } } if (*ret == RHN_OK) { if ((j_return = _r_jwe_ecdh_encrypt(jwe, alg, jwk, jwk_priv, res, bits, x5u_flags, ret)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Error _r_jwe_ecdh_encrypt"); } } r_jwk_free(jwk_priv); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - invalid public key type"); *ret = RHN_ERROR_PARAM; } break; #endif default: y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_perform_key_encryption - Unsupported alg"); *ret = RHN_ERROR_PARAM; break; } j_key_ref_array = json_array(); json_object_foreach(json_object_get(j_return, "header"), key_ref, j_element) { j_reference = json_object_get(jwe->j_header, key_ref); if (j_reference == NULL) { j_reference = json_object_get(jwe->j_unprotected_header, key_ref); } if (j_reference != NULL && json_equal(j_reference, j_element)) { json_array_append_new(j_key_ref_array, json_string(key_ref)); } } json_array_foreach(j_key_ref_array, index, j_element) { json_object_del(json_object_get(j_return, "header"), json_string_value(j_element)); } json_decref(j_key_ref_array); if (!json_object_size(json_object_get(j_return, "header"))) { json_object_del(j_return, "header"); } return j_return; } static int _r_preform_key_decryption(jwe_t * jwe, jwa_alg alg, jwk_t * jwk, int x5u_flags) { int ret, res; gnutls_datum_t plainkey = {NULL, 0}, cypherkey; gnutls_privkey_t g_priv = NULL; unsigned int bits = 0; unsigned char * key = NULL; size_t key_len = 0; struct _o_datum dat = {0, NULL}; #if NETTLE_VERSION_NUMBER >= 0x030400 uint8_t * clearkey = NULL; size_t clearkey_len = 0; #endif switch (alg) { case R_JWA_ALG_RSA1_5: res = r_jwk_key_type(jwk, &bits, x5u_flags); if (res & R_KEY_TYPE_RSA && res & R_KEY_TYPE_PRIVATE && bits >= 2048) { if (jwk != NULL && !o_strnullempty((const char *)jwe->encrypted_key_b64url) && (g_priv = r_jwk_export_to_gnutls_privkey(jwk)) != NULL) { if (o_base64url_decode_alloc(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), &dat)) { cypherkey.size = (unsigned int)dat.size; cypherkey.data = dat.data; if (!(res = gnutls_privkey_decrypt_data(g_priv, 0, &cypherkey, &plainkey))) { if (r_jwe_set_cypher_key(jwe, plainkey.data, plainkey.size) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwe_set_cypher_key (RSA1_5)"); ret = RHN_ERROR; } gnutls_free(plainkey.data); } else if (res == GNUTLS_E_DECRYPTION_FAILED) { ret = RHN_ERROR_INVALID; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error gnutls_privkey_decrypt_data: %s", gnutls_strerror(res)); ret = RHN_ERROR; } o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error o_base64url_decode_alloc encrypted_key_b64url"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid RSA1_5 input parameters"); ret = RHN_ERROR_PARAM; } gnutls_privkey_deinit(g_priv); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key size RSA1_5"); ret = RHN_ERROR_INVALID; } break; #if NETTLE_VERSION_NUMBER >= 0x030400 case R_JWA_ALG_RSA_OAEP: case R_JWA_ALG_RSA_OAEP_256: res = r_jwk_key_type(jwk, &bits, x5u_flags); if (res & R_KEY_TYPE_RSA && res & R_KEY_TYPE_PRIVATE && bits >= 2048) { if (jwk != NULL && !o_strnullempty((const char *)jwe->encrypted_key_b64url) && (g_priv = r_jwk_export_to_gnutls_privkey(jwk)) != NULL) { if (o_base64url_decode_alloc(jwe->encrypted_key_b64url, o_strlen((const char *)jwe->encrypted_key_b64url), &dat)) { if ((clearkey = o_malloc(bits+1)) != NULL) { clearkey_len = bits+1; if (_r_rsa_oaep_decrypt(g_priv, alg, dat.data, dat.size, clearkey, &clearkey_len) == RHN_OK) { if (_r_get_key_size(jwe->enc) == clearkey_len) { if (r_jwe_set_cypher_key(jwe, clearkey, clearkey_len) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwe_set_cypher_key (RSA_OAEP)"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key length"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error _r_rsa_oaep_decrypt"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error o_malloc clearkey"); ret = RHN_ERROR_MEMORY; } o_free(clearkey); o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error o_base64url_decode_alloc encrypted_key_b64url"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid RSA1-OAEP input parameters"); ret = RHN_ERROR_PARAM; } gnutls_privkey_deinit(g_priv); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key size RSA_OAEP"); ret = RHN_ERROR_INVALID; } break; #endif case R_JWA_ALG_DIR: o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; if (jwk != NULL) { if (r_jwk_key_type(jwk, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC && bits == _r_get_key_size(jwe->enc)*8) { key_len = (size_t)(bits/8); if ((key = o_malloc(key_len+4)) != NULL) { if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) == RHN_OK) { o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; ret = r_jwe_set_cypher_key(jwe, key, key_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwk_export_to_symmetric_key"); ret = RHN_ERROR_MEMORY; } o_free(key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key type DIR"); ret = RHN_ERROR_INVALID; } } else if (jwe->key != NULL && jwe->key_len > 0) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error no key available for alg 'dir'"); ret = RHN_ERROR_INVALID; } break; case R_JWA_ALG_A128GCMKW: #if GNUTLS_VERSION_NUMBER >= 0x03060e case R_JWA_ALG_A192GCMKW: #endif case R_JWA_ALG_A256GCMKW: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { if ((res = r_jwe_aesgcm_key_unwrap(jwe, alg, jwk, x5u_flags)) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwe_aesgcm_key_unwrap"); ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key type AESGCM"); ret = RHN_ERROR_INVALID; } break; #if NETTLE_VERSION_NUMBER >= 0x030400 case R_JWA_ALG_A128KW: case R_JWA_ALG_A192KW: case R_JWA_ALG_A256KW: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { if ((res = r_jwe_aes_key_unwrap(jwe, alg, jwk, x5u_flags)) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwe_aes_key_unwrap"); ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key type KeyWrap"); ret = RHN_ERROR_INVALID; } break; #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d case R_JWA_ALG_PBES2_H256: case R_JWA_ALG_PBES2_H384: case R_JWA_ALG_PBES2_H512: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_SYMMETRIC) { if ((res = r_jwe_pbes2_key_unwrap(jwe, alg, jwk, x5u_flags)) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error r_jwe_pbes2_key_unwrap"); ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key type PBES"); ret = RHN_ERROR_INVALID; } break; #endif #if NETTLE_VERSION_NUMBER >= 0x030600 case R_JWA_ALG_ECDH_ES: case R_JWA_ALG_ECDH_ES_A128KW: case R_JWA_ALG_ECDH_ES_A192KW: case R_JWA_ALG_ECDH_ES_A256KW: res = r_jwk_key_type(jwk, &bits, x5u_flags); if (res & (R_KEY_TYPE_EC|R_KEY_TYPE_ECDH) && res & R_KEY_TYPE_PRIVATE && bits < 521) { if ((res = _r_jwe_ecdh_decrypt(jwe, alg, jwk, res, bits, x5u_flags)) == RHN_OK) { ret = RHN_OK; } else { if (res != RHN_ERROR_INVALID) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error _r_jwe_ecdh_decrypt"); } ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error invalid key type ECDH"); ret = RHN_ERROR_INVALID; } break; #endif default: y_log_message(Y_LOG_LEVEL_ERROR, "_r_preform_key_decryption - Error unsupported algorithm"); ret = RHN_ERROR_INVALID; break; } return ret; } int r_jwe_init(jwe_t ** jwe) { int ret; if (jwe != NULL) { if ((*jwe = o_malloc(sizeof(jwe_t))) != NULL) { if (((*jwe)->j_header = json_object()) != NULL) { if (r_jwks_init(&(*jwe)->jwks_pubkey) == RHN_OK) { if (r_jwks_init(&(*jwe)->jwks_privkey) == RHN_OK) { (*jwe)->header_b64url = NULL; (*jwe)->encrypted_key_b64url = NULL; (*jwe)->iv_b64url = NULL; (*jwe)->aad_b64url = NULL; (*jwe)->ciphertext_b64url = NULL; (*jwe)->auth_tag_b64url = NULL; (*jwe)->j_unprotected_header = NULL; (*jwe)->alg = R_JWA_ALG_UNKNOWN; (*jwe)->enc = R_JWA_ENC_UNKNOWN; (*jwe)->key = NULL; (*jwe)->key_len = 0; (*jwe)->iv = NULL; (*jwe)->iv_len = 0; (*jwe)->aad = NULL; (*jwe)->aad_len = 0; (*jwe)->payload = NULL; (*jwe)->payload_len = 0; (*jwe)->j_json_serialization = NULL; (*jwe)->token_mode = R_JSON_MODE_COMPACT; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_init - Error allocating resources for jwks_privkey"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_init - Error allocating resources for jwks_pubkey"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_init - Error allocating resources for j_header"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_init - Error allocating resources for jwe"); ret = RHN_ERROR_MEMORY; } } else { ret = RHN_ERROR_PARAM; } if (ret != RHN_OK && jwe != NULL) { r_jwe_free(*jwe); *jwe = NULL; } return ret; } void r_jwe_free(jwe_t * jwe) { if (jwe != NULL) { r_jwks_free(jwe->jwks_privkey); r_jwks_free(jwe->jwks_pubkey); o_free(jwe->header_b64url); o_free(jwe->encrypted_key_b64url); o_free(jwe->iv_b64url); o_free(jwe->aad_b64url); o_free(jwe->ciphertext_b64url); o_free(jwe->auth_tag_b64url); json_decref(jwe->j_header); json_decref(jwe->j_unprotected_header); json_decref(jwe->j_json_serialization); o_free(jwe->key); o_free(jwe->iv); o_free(jwe->aad); o_free(jwe->payload); o_free(jwe); } } jwe_t * r_jwe_copy(jwe_t * jwe) { jwe_t * jwe_copy = NULL; if (jwe != NULL) { if (r_jwe_init(&jwe_copy) == RHN_OK) { jwe_copy->alg = jwe->alg; jwe_copy->enc = jwe->enc; jwe_copy->token_mode = jwe->token_mode; if (r_jwe_set_payload(jwe_copy, jwe->payload, jwe->payload_len) == RHN_OK && r_jwe_set_iv(jwe_copy, jwe->iv, jwe->iv_len) == RHN_OK && r_jwe_set_aad(jwe_copy, jwe->aad, jwe->aad_len) == RHN_OK && r_jwe_set_cypher_key(jwe_copy, jwe->key, jwe->key_len) == RHN_OK && r_jwe_set_alg(jwe_copy, r_jwe_get_alg(jwe)) == RHN_OK) { jwe_copy->header_b64url = (unsigned char *)o_strdup((const char *)jwe->header_b64url); jwe_copy->encrypted_key_b64url = (unsigned char *)o_strdup((const char *)jwe->encrypted_key_b64url); jwe_copy->ciphertext_b64url = (unsigned char *)o_strdup((const char *)jwe->ciphertext_b64url); jwe_copy->auth_tag_b64url = (unsigned char *)o_strdup((const char *)jwe->auth_tag_b64url); r_jwks_free(jwe_copy->jwks_privkey); jwe_copy->jwks_privkey = r_jwks_copy(jwe->jwks_privkey); r_jwks_free(jwe_copy->jwks_pubkey); jwe_copy->jwks_pubkey = r_jwks_copy(jwe->jwks_pubkey); json_decref(jwe_copy->j_header); jwe_copy->j_header = json_deep_copy(jwe->j_header); jwe_copy->j_unprotected_header = json_deep_copy(jwe->j_unprotected_header); jwe_copy->j_json_serialization = json_deep_copy(jwe->j_json_serialization); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_copy - Error setting values"); r_jwe_free(jwe_copy); jwe_copy = NULL; } } } return jwe_copy; } int r_jwe_set_payload(jwe_t * jwe, const unsigned char * payload, size_t payload_len) { int ret; if (jwe != NULL) { o_free(jwe->payload); if (payload != NULL && payload_len) { if ((jwe->payload = o_malloc(payload_len)) != NULL) { memcpy(jwe->payload, payload, payload_len); jwe->payload_len = payload_len; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_payload - Error allocating resources for payload"); ret = RHN_ERROR_MEMORY; } } else { jwe->payload = NULL; jwe->payload_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwe_get_payload(jwe_t * jwe, size_t * payload_len) { if (jwe != NULL) { if (payload_len != NULL) { *payload_len = jwe->payload_len; } return jwe->payload; } return NULL; } int r_jwe_set_cypher_key(jwe_t * jwe, const unsigned char * key, size_t key_len) { int ret; if (jwe != NULL) { o_free(jwe->key); if (key != NULL && key_len) { if ((jwe->key = o_malloc(key_len)) != NULL) { memcpy(jwe->key, key, key_len); jwe->key_len = key_len; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_cypher_key - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; } } else { jwe->key = NULL; jwe->key_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwe_get_cypher_key(jwe_t * jwe, size_t * key_len) { if (jwe != NULL) { if (key_len != NULL) { *key_len = jwe->key_len; } return jwe->key; } return NULL; } int r_jwe_generate_cypher_key(jwe_t * jwe) { int ret; if (jwe != NULL && jwe->enc != R_JWA_ENC_UNKNOWN) { o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; jwe->key_len = _r_get_key_size(jwe->enc); o_free(jwe->key); if (!jwe->key_len) { ret = RHN_ERROR_PARAM; } else if ((jwe->key = o_malloc(jwe->key_len)) != NULL) { if (!gnutls_rnd(GNUTLS_RND_KEY, jwe->key, jwe->key_len)) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_cypher_key - Error gnutls_rnd"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_cypher_key - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_cypher_key - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_set_iv(jwe_t * jwe, const unsigned char * iv, size_t iv_len) { int ret; struct _o_datum dat = {0, NULL}; if (jwe != NULL) { o_free(jwe->iv); if (iv != NULL && iv_len) { if ((jwe->iv = o_malloc(iv_len)) != NULL) { memcpy(jwe->iv, iv, iv_len); jwe->iv_len = iv_len; if (o_base64url_encode_alloc(jwe->iv, jwe->iv_len, &dat)) { o_free(jwe->iv_b64url); jwe->iv_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_iv - Error o_base64url_encode_alloc iv"); ret = RHN_ERROR; } ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_iv - Error allocating resources for iv"); ret = RHN_ERROR_MEMORY; } } else { jwe->iv = NULL; jwe->iv_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwe_get_iv(jwe_t * jwe, size_t * iv_len) { if (jwe != NULL) { if (iv_len != NULL) { *iv_len = jwe->iv_len; } return jwe->iv; } return NULL; } int r_jwe_set_aad(jwe_t * jwe, const unsigned char * aad, size_t aad_len) { int ret; struct _o_datum dat = {0, NULL}; if (jwe != NULL) { o_free(jwe->aad_b64url); jwe->aad_b64url = NULL; o_free(jwe->aad); if (aad != NULL && aad_len) { if ((jwe->aad = o_malloc(aad_len)) != NULL) { memcpy(jwe->aad, aad, aad_len); jwe->aad_len = aad_len; if (o_base64url_encode_alloc(jwe->aad, jwe->aad_len, &dat)) { o_free(jwe->aad_b64url); jwe->aad_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_aad - Error o_base64url_encode_alloc aad"); ret = RHN_ERROR; } ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_aad - Error allocating resources for aad"); ret = RHN_ERROR_MEMORY; } } else { jwe->aad = NULL; jwe->aad_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwe_get_aad(jwe_t * jwe, size_t * aad_len) { if (jwe != NULL) { if (aad_len != NULL) { *aad_len = jwe->aad_len; } return jwe->aad; } return NULL; } int r_jwe_generate_iv(jwe_t * jwe) { int ret; struct _o_datum dat = {0, NULL}; if (jwe != NULL && jwe->enc != R_JWA_ENC_UNKNOWN) { o_free(jwe->iv_b64url); jwe->iv_b64url = NULL; jwe->iv_len = (unsigned)gnutls_cipher_get_iv_size(_r_get_alg_from_enc(jwe->enc)); o_free(jwe->iv); jwe->iv = NULL; if (jwe->iv_len) { if ((jwe->iv = o_malloc(jwe->iv_len)) != NULL) { if (!gnutls_rnd(GNUTLS_RND_NONCE, jwe->iv, jwe->iv_len)) { if (o_base64url_encode_alloc(jwe->iv, jwe->iv_len, &dat)) { jwe->iv_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_iv - Error o_base64url_encode iv_b64"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_iv - Error gnutls_rnd"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_generate_iv - Error allocating resources for iv"); ret = RHN_ERROR_MEMORY; } } else { jwe->iv_b64url = (unsigned char *)o_strdup(""); ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_set_alg(jwe_t * jwe, jwa_alg alg) { int ret = RHN_OK; if (jwe != NULL) { jwe->alg = alg; } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_alg r_jwe_get_alg(jwe_t * jwe) { if (jwe != NULL) { return jwe->alg; } else { return R_JWA_ALG_UNKNOWN; } } int r_jwe_set_enc(jwe_t * jwe, jwa_enc enc) { int ret = RHN_OK; if (jwe != NULL) { jwe->enc = enc; } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_enc r_jwe_get_enc(jwe_t * jwe) { if (jwe != NULL) { return jwe->enc; } else { return R_JWA_ENC_UNKNOWN; } } const char * r_jwe_get_kid(jwe_t * jwe) { return r_jwe_get_header_str_value(jwe, "kid"); } int r_jwe_set_header_str_value(jwe_t * jwe, const char * key, const char * str_value) { int ret; if (jwe != NULL) { if ((ret = _r_json_set_str_value(jwe->j_header, key, str_value)) == RHN_OK) { o_free(jwe->header_b64url); jwe->header_b64url = NULL; } return ret; } else { return RHN_ERROR_PARAM; } } int r_jwe_set_header_int_value(jwe_t * jwe, const char * key, rhn_int_t i_value) { int ret; if (jwe != NULL) { if ((ret = _r_json_set_int_value(jwe->j_header, key, i_value)) == RHN_OK) { o_free(jwe->header_b64url); jwe->header_b64url = NULL; } return ret; } else { return RHN_ERROR_PARAM; } } int r_jwe_set_header_json_t_value(jwe_t * jwe, const char * key, json_t * j_value) { int ret; if (jwe != NULL) { if ((ret = _r_json_set_json_t_value(jwe->j_header, key, j_value)) == RHN_OK) { o_free(jwe->header_b64url); jwe->header_b64url = NULL; } return ret; } else { ret = RHN_ERROR_PARAM; } return ret; } const char * r_jwe_get_header_str_value(jwe_t * jwe, const char * key) { if (jwe != NULL) { return _r_json_get_str_value(jwe->j_header, key); } return NULL; } rhn_int_t r_jwe_get_header_int_value(jwe_t * jwe, const char * key) { if (jwe != NULL) { return _r_json_get_int_value(jwe->j_header, key); } return 0; } json_t * r_jwe_get_header_json_t_value(jwe_t * jwe, const char * key) { if (jwe != NULL) { return _r_json_get_json_t_value(jwe->j_header, key); } return NULL; } json_t * r_jwe_get_full_header_json_t(jwe_t * jwe) { if (jwe != NULL) { return _r_json_get_full_json_t(jwe->j_header); } return NULL; } char * r_jwe_get_full_header_str(jwe_t * jwe) { char * to_return = NULL; if (jwe != NULL) { to_return = json_dumps(jwe->j_header, JSON_COMPACT); } return to_return; } json_t * r_jwe_get_full_unprotected_header_json_t(jwe_t * jwe) { if (jwe != NULL) { return _r_json_get_full_json_t(jwe->j_unprotected_header); } return NULL; } char * r_jwe_get_full_unprotected_header_str(jwe_t * jwe) { char * to_return = NULL; if (jwe != NULL) { to_return = json_dumps(jwe->j_unprotected_header, JSON_COMPACT); } return to_return; } int r_jwe_add_keys(jwe_t * jwe, jwk_t * jwk_privkey, jwk_t * jwk_pubkey) { int ret = RHN_OK; jwa_alg alg; if (jwe != NULL && (jwk_privkey != NULL || jwk_pubkey != NULL)) { if (jwk_privkey != NULL) { if (r_jwks_append_jwk(jwe->jwks_privkey, jwk_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys - Error setting jwk_privkey"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } if (jwk_pubkey != NULL) { if (r_jwks_append_jwk(jwe->jwks_pubkey, jwk_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys - Error setting jwk_pubkey"); ret = RHN_ERROR; } } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_add_jwks(jwe_t * jwe, jwks_t * jwks_privkey, jwks_t * jwks_pubkey) { size_t i; int ret, res; jwk_t * jwk; if (jwe != NULL && (jwks_privkey != NULL || jwks_pubkey != NULL)) { ret = RHN_OK; if (jwks_privkey != NULL) { for (i=0; ret==RHN_OK && ijwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_str - Error setting privkey"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_str - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_str(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_str - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_str - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_add_keys_json_t(jwe_t * jwe, json_t * privkey, json_t * pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwe != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_json_t(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_t - Error setting privkey"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_t - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_t(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_t - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_json_t - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_add_keys_pem_der(jwe_t * jwe, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwe != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_pem_der(j_privkey, R_X509_TYPE_PRIVKEY, format, privkey, privkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_pem_der - Error setting privkey"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_pem_der - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_pem_der(j_pubkey, R_X509_TYPE_PUBKEY, format, pubkey, pubkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_pem_der - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_pem_der - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_add_keys_gnutls(jwe_t * jwe, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwe != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_gnutls_privkey(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_gnutls - Error setting privkey"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_gnutls - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_gnutls_pubkey(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_gnutls - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_keys_gnutls - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_add_key_symmetric(jwe_t * jwe, const unsigned char * key, size_t key_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_key = NULL; if (jwe != NULL && key != NULL && key_len) { if (r_jwk_init(&j_key) == RHN_OK && r_jwk_import_from_symmetric_key(j_key, key, key_len) == RHN_OK) { if (r_jwks_append_jwk(jwe->jwks_privkey, j_key) != RHN_OK || r_jwks_append_jwk(jwe->jwks_pubkey, j_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_enc_key_symmetric - Error setting key"); ret = RHN_ERROR; } if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_key, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_add_enc_key_symmetric - Error parsing key"); ret = RHN_ERROR; } r_jwk_free(j_key); } else { ret = RHN_ERROR_PARAM; } return ret; } jwks_t * r_jwe_get_jwks_privkey(jwe_t * jwe) { if (jwe != NULL) { return r_jwks_copy(jwe->jwks_privkey); } else { return NULL; } } jwks_t * r_jwe_get_jwks_pubkey(jwe_t * jwe) { if (jwe != NULL) { return r_jwks_copy(jwe->jwks_pubkey); } else { return NULL; } } int r_jwe_encrypt_payload(jwe_t * jwe) { int ret = RHN_OK, res; gnutls_cipher_hd_t handle; gnutls_datum_t key, iv; unsigned char * ptext = NULL, * text_zip = NULL, * ciphertext_b64url = NULL, tag[128] = {0}, * tag_b64url = NULL, * aad = NULL; size_t ptext_len = 0, ciphertext_b64url_len = 0, tag_len = 0, text_zip_len = 0; char * str_header = NULL; int cipher_cbc; struct _o_datum dat = {0, NULL}; if (jwe != NULL && jwe->payload != NULL && jwe->payload_len && jwe->enc != R_JWA_ENC_UNKNOWN && jwe->key != NULL && jwe->iv != NULL && jwe->iv_len && jwe->key_len == _r_get_key_size(jwe->enc) && r_jwe_set_enc_header(jwe, jwe->j_header) == RHN_OK) { cipher_cbc = (jwe->enc == R_JWA_ENC_A128CBC || jwe->enc == R_JWA_ENC_A192CBC || jwe->enc == R_JWA_ENC_A256CBC); if ((str_header = json_dumps(jwe->j_header, JSON_COMPACT)) != NULL) { if (o_base64url_encode_alloc((const unsigned char *)str_header, o_strlen(str_header), &dat)) { o_free(jwe->header_b64url); jwe->header_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error o_base64url_encode str_header"); ret = RHN_ERROR; } o_free(str_header); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error json_dumps j_header"); ret = RHN_ERROR; } ptext_len = (unsigned)gnutls_cipher_get_block_size(_r_get_alg_from_enc(jwe->enc)); if (0 == o_strcmp("DEF", r_jwe_get_header_str_value(jwe, "zip"))) { if (_r_deflate_payload(jwe->payload, jwe->payload_len, &text_zip, &text_zip_len) == RHN_OK) { if (r_jwe_set_ptext_with_block(text_zip, text_zip_len, &ptext, &ptext_len, _r_get_alg_from_enc(jwe->enc), cipher_cbc) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error r_jwe_set_ptext_with_block"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error _r_deflate_payload"); ret = RHN_ERROR; } o_free(text_zip); } else { if (r_jwe_set_ptext_with_block(jwe->payload, jwe->payload_len, &ptext, &ptext_len, _r_get_alg_from_enc(jwe->enc), cipher_cbc) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error r_jwe_set_ptext_with_block"); ret = RHN_ERROR; } } if (ret == RHN_OK) { if (cipher_cbc) { key.data = jwe->key+(jwe->key_len/2); key.size = (unsigned int)jwe->key_len/2; } else { key.data = jwe->key; key.size = (unsigned int)jwe->key_len; } iv.data = jwe->iv; iv.size = (unsigned int)jwe->iv_len; if (!(res = gnutls_cipher_init(&handle, _r_get_alg_from_enc(jwe->enc), &key, &iv))) { if (jwe->aad_b64url == NULL || jwe->token_mode == R_JSON_MODE_COMPACT) { aad = (unsigned char *)o_strdup((const char *)jwe->header_b64url); } else { aad = (unsigned char *)msprintf("%s.%s", jwe->header_b64url, jwe->aad_b64url); } if (!cipher_cbc && (res = gnutls_cipher_add_auth(handle, aad, o_strlen((const char *)aad)))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error gnutls_cipher_add_auth: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } if (ret == RHN_OK) { if (!(res = gnutls_cipher_encrypt(handle, ptext, ptext_len))) { if ((ciphertext_b64url = o_malloc(2*ptext_len)) != NULL) { if (o_base64url_encode(ptext, ptext_len, ciphertext_b64url, &ciphertext_b64url_len)) { o_free(jwe->ciphertext_b64url); jwe->ciphertext_b64url = (unsigned char *)o_strndup((const char *)ciphertext_b64url, ciphertext_b64url_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error o_base64url_encode ciphertext"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error allocating resources for ciphertext_b64url"); ret = RHN_ERROR_MEMORY; } o_free(ciphertext_b64url); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error gnutls_cipher_encrypt: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } } else if (!cipher_cbc) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error gnutls_cipher_add_auth: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } if (ret == RHN_OK) { if (cipher_cbc) { if (r_jwe_compute_hmac_tag(jwe, ptext, ptext_len, aad, tag, &tag_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error r_jwe_compute_hmac_tag"); ret = RHN_ERROR; } } else { tag_len = (unsigned)gnutls_cipher_get_tag_size(_r_get_alg_from_enc(jwe->enc)); memset(tag, 0, tag_len); if ((res = gnutls_cipher_tag(handle, tag, tag_len))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error gnutls_cipher_tag: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } } if (ret == RHN_OK && tag_len) { if ((tag_b64url = o_malloc(tag_len*2)) != NULL) { if (o_base64url_encode_alloc(tag, tag_len, &dat)) { o_free(jwe->auth_tag_b64url); jwe->auth_tag_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); dat.data = NULL; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error o_base64url_encode tag_b64url"); ret = RHN_ERROR; } o_free(tag_b64url); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error allocating resources for tag_b64url"); ret = RHN_ERROR_MEMORY; } } } o_free(aad); gnutls_cipher_deinit(handle); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error gnutls_cipher_init: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_payload - Error input parameters"); ret = RHN_ERROR_PARAM; } o_free(ptext); return ret; } static int _r_gnutls_is_block_cipher(gnutls_cipher_algorithm_t alg) { switch (alg) { case GNUTLS_CIPHER_3DES_CBC: case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_256_CBC: case GNUTLS_CIPHER_CAMELLIA_128_CBC: case GNUTLS_CIPHER_CAMELLIA_256_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_CAMELLIA_192_CBC : case GNUTLS_CIPHER_RC2_40_CBC : case GNUTLS_CIPHER_DES_CBC: return 1; default: return 0; } } int r_jwe_decrypt_payload(jwe_t * jwe) { int ret = RHN_OK, res; gnutls_cipher_hd_t handle; gnutls_datum_t key, iv; unsigned char * payload_enc = NULL, * unzip = NULL, * aad = NULL; size_t payload_enc_len = 0, unzip_len = 0; unsigned char tag[128]; size_t tag_len = 0; size_t ciphertext_b64_len; size_t ciphertext_decoded_len = 0; unsigned cipher_block_size; int cipher_cbc; struct _o_datum dat = {0, NULL}, dat_ciph = {0, NULL}, dat_tag = {0, NULL}; if (jwe != NULL && jwe->enc != R_JWA_ENC_UNKNOWN && (ciphertext_b64_len = o_strlen((const char *)jwe->ciphertext_b64url)) != 0 && !o_strnullempty((const char *)jwe->iv_b64url) && jwe->key != NULL && jwe->key_len && jwe->key_len == _r_get_key_size(jwe->enc)) { /* ensure payload_enc_buflen is a multiple of cipher_block_size * if the cipher is a block-mode cipher */ if (_r_gnutls_is_block_cipher(_r_get_alg_from_enc(jwe->enc))) { if (o_base64url_decode(jwe->ciphertext_b64url, ciphertext_b64_len, NULL, &ciphertext_decoded_len)) { cipher_block_size = (unsigned)gnutls_cipher_get_block_size(_r_get_alg_from_enc(jwe->enc)); if (!ciphertext_decoded_len || ciphertext_decoded_len % cipher_block_size) { /* The ciphertext length is not a multiple of block size. * It can't possibly be valid */ y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Invalid ciphertext length"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error o_base64url_decode ciphertext_b64url"); ret = RHN_ERROR; } } if (ret == RHN_OK) { // Decode iv and payload_b64 o_free(jwe->iv); if (o_base64url_decode_alloc(jwe->iv_b64url, o_strlen((const char *)jwe->iv_b64url), &dat)) { if ((jwe->iv = o_malloc(dat.size)) != NULL) { jwe->iv_len = dat.size; memcpy(jwe->iv, dat.data, dat.size); if (o_base64url_decode_alloc(jwe->ciphertext_b64url, ciphertext_b64_len, &dat_ciph)) { if ((payload_enc = o_malloc(dat_ciph.size)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error allocating resources for payload_enc"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error o_base64url_decode_alloc ciphertext_b64url"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error reallocating resources for iv"); ret = RHN_ERROR_MEMORY; } o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error o_base64url_decode_alloc iv"); ret = RHN_ERROR; } } if (ret == RHN_OK) { if (jwe->enc == R_JWA_ENC_A128CBC || jwe->enc == R_JWA_ENC_A192CBC || jwe->enc == R_JWA_ENC_A256CBC) { key.data = jwe->key+(jwe->key_len/2); key.size = (unsigned int)jwe->key_len/2; cipher_cbc = 1; } else { key.data = jwe->key; key.size = (unsigned int)jwe->key_len; cipher_cbc = 0; } iv.data = jwe->iv; iv.size = (unsigned int)jwe->iv_len; payload_enc_len = dat_ciph.size; if (!(res = gnutls_cipher_init(&handle, _r_get_alg_from_enc(jwe->enc), &key, &iv))) { if (jwe->aad_b64url == NULL || jwe->token_mode == R_JSON_MODE_COMPACT) { aad = (unsigned char *)o_strdup((const char *)jwe->header_b64url); } else { aad = (unsigned char *)msprintf("%s.%s", jwe->header_b64url, jwe->aad_b64url); } if (!cipher_cbc && (res = gnutls_cipher_add_auth(handle, aad, o_strlen((const char *)aad)))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error gnutls_cipher_add_auth: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } if (!(res = gnutls_cipher_decrypt2(handle, dat_ciph.data, dat_ciph.size, payload_enc, payload_enc_len))) { if (cipher_cbc) { r_jwe_remove_padding(payload_enc, &payload_enc_len, (unsigned)gnutls_cipher_get_block_size(_r_get_alg_from_enc(jwe->enc))); } if (0 == o_strcmp("DEF", r_jwe_get_header_str_value(jwe, "zip"))) { if (_r_inflate_payload(payload_enc, payload_enc_len, &unzip, &unzip_len) == RHN_OK) { if (r_jwe_set_payload(jwe, unzip, unzip_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error r_jwe_set_payload"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error _r_inflate_payload"); ret = RHN_ERROR; } o_free(unzip); } else { if (r_jwe_set_payload(jwe, payload_enc, payload_enc_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error r_jwe_set_payload"); ret = RHN_ERROR; } } } else if (res == GNUTLS_E_INVALID_REQUEST) { ret = RHN_ERROR_INVALID; } else if (res == GNUTLS_E_DECRYPTION_FAILED) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - decryption failed: '%s'", gnutls_strerror(res)); ret = RHN_ERROR_INVALID; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error gnutls_cipher_decrypt: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } if (ret == RHN_OK) { if (cipher_cbc) { if (r_jwe_compute_hmac_tag(jwe, dat_ciph.data, dat_ciph.size, aad, tag, &tag_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error r_jwe_compute_hmac_tag"); ret = RHN_ERROR; } } else { tag_len = (unsigned)gnutls_cipher_get_tag_size(_r_get_alg_from_enc(jwe->enc)); memset(tag, 0, tag_len); if ((res = gnutls_cipher_tag(handle, tag, tag_len))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error gnutls_cipher_tag: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } } if (ret == RHN_OK && tag_len) { if (o_base64url_encode_alloc(tag, tag_len, &dat_tag)) { if (dat_tag.size != o_strlen((const char *)jwe->auth_tag_b64url) || 0 != memcmp(dat_tag.data, jwe->auth_tag_b64url, dat_tag.size)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Invalid tag"); ret = RHN_ERROR_INVALID; } o_free(dat_tag.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error o_base64url_encode_alloc tag"); ret = RHN_ERROR; } } } o_free(aad); gnutls_cipher_deinit(handle); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error gnutls_cipher_init: '%s'", gnutls_strerror(res)); ret = RHN_ERROR; } } } else if (jwe != NULL && jwe->key_len != _r_get_key_size(jwe->enc)) { ret = RHN_ERROR_INVALID; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt_payload - Error input parameters"); ret = RHN_ERROR_PARAM; } o_free(payload_enc); o_free(dat_ciph.data); return ret; } int r_jwe_encrypt_key(jwe_t * jwe, jwk_t * jwk_s, int x5u_flags) { int ret, res = RHN_OK; jwk_t * jwk = NULL; jwa_alg alg; const char * kid; json_t * j_header = NULL, * j_cur_header = NULL; if (jwe != NULL) { if (jwk_s != NULL) { jwk = r_jwk_copy(jwk_s); if (jwe->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk, "alg"))) != R_JWA_ALG_NONE) { r_jwe_set_alg(jwe, alg); } } else { if (r_jwe_get_header_str_value(jwe, "kid") != NULL) { jwk = r_jwks_get_by_kid(jwe->jwks_pubkey, r_jwe_get_header_str_value(jwe, "kid")); } else if (r_jwks_size(jwe->jwks_pubkey) == 1) { jwk = r_jwks_get_at(jwe->jwks_pubkey, 0); } } } if (jwe != NULL && jwe->key != NULL && jwe->key_len && jwe->alg != R_JWA_ALG_UNKNOWN && jwe->alg != R_JWA_ALG_NONE) { if ((kid = r_jwk_get_property_str(jwk, "kid")) != NULL && r_jwe_get_header_str_value(jwe, "kid") == NULL) { r_jwe_set_header_str_value(jwe, "kid", kid); } if ((j_header = r_jwe_perform_key_encryption(jwe, jwe->alg, jwk, x5u_flags, &res)) != NULL) { j_cur_header = r_jwe_get_full_header_json_t(jwe); json_object_update(j_cur_header, json_object_get(j_header, "header")); r_jwe_set_full_header_json_t(jwe, j_cur_header); json_decref(j_cur_header); o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(j_header, "encrypted_key"))); json_decref(j_header); ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_key - Error r_jwe_perform_key_encryption"); ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_encrypt_key - invalid input parameters"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); return ret; } int r_jwe_decrypt_key(jwe_t * jwe, jwk_t * jwk_s, int x5u_flags) { int ret; jwk_t * jwk = NULL; if (jwe != NULL) { if (jwk_s != NULL) { jwk = r_jwk_copy(jwk_s); } else { if (r_jwe_get_header_str_value(jwe, "kid") != NULL) { jwk = r_jwks_get_by_kid(jwe->jwks_privkey, r_jwe_get_header_str_value(jwe, "kid")); } else if (r_jwks_size(jwe->jwks_privkey) == 1) { jwk = r_jwks_get_at(jwe->jwks_privkey, 0); } } } if (jwe != NULL && jwe->alg != R_JWA_ALG_UNKNOWN && jwe->alg != R_JWA_ALG_NONE) { ret = _r_preform_key_decryption(jwe, jwe->alg, jwk, x5u_flags); } else { ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); return ret; } int r_jwe_parse(jwe_t * jwe, const char * jwe_str, int x5u_flags) { return r_jwe_parsen(jwe, jwe_str, o_strlen(jwe_str), x5u_flags); } int r_jwe_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, int x5u_flags) { int ret; char * str = (char *)jwe_str; if (jwe != NULL && str != NULL && jwe_str_len) { while(isspace((unsigned char)*str) && jwe_str_len) { str++; jwe_str_len--; } if (0 == o_strncmp("ey", str, 2)) { ret = r_jwe_compact_parsen(jwe, jwe_str, jwe_str_len, x5u_flags); } else if (*str == '{') { ret = r_jwe_parsen_json_str(jwe, jwe_str, jwe_str_len, x5u_flags); } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_advanced_parse(jwe_t * jwe, const char * jwe_str, uint32_t parse_flags, int x5u_flags) { return r_jwe_advanced_parsen(jwe, jwe_str, o_strlen(jwe_str), parse_flags, x5u_flags); } int r_jwe_advanced_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags) { int ret; char * str = (char *)jwe_str; if (jwe != NULL && str != NULL && jwe_str_len) { while(isspace((unsigned char)*str) && jwe_str_len) { str++; jwe_str_len--; } if (0 == o_strncmp("ey", str, 2)) { ret = r_jwe_advanced_compact_parsen(jwe, jwe_str, jwe_str_len, parse_flags, x5u_flags); } else if (*str == '{') { ret = r_jwe_advanced_parsen_json_str(jwe, jwe_str, jwe_str_len, parse_flags, x5u_flags); } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_compact_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, int x5u_flags) { return r_jwe_advanced_compact_parsen(jwe, jwe_str, jwe_str_len, R_PARSE_HEADER_ALL, x5u_flags); } int r_jwe_compact_parse(jwe_t * jwe, const char * jwe_str, int x5u_flags) { return r_jwe_compact_parsen(jwe, jwe_str, o_strlen(jwe_str), x5u_flags); } int r_jwe_advanced_compact_parse(jwe_t * jwe, const char * jwe_str, uint32_t parse_flags, int x5u_flags) { return r_jwe_advanced_compact_parsen(jwe, jwe_str, o_strlen(jwe_str), parse_flags, x5u_flags); } int r_jwe_advanced_compact_parsen(jwe_t * jwe, const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags) { int ret; char ** str_array = NULL; char * token = NULL; size_t cypher_key_len = 0, cypher_len = 0, tag_len = 0; json_t * j_header = NULL; struct _o_datum dat_header = {0, NULL}, dat_iv = {0, NULL}; if (jwe != NULL && jwe_str != NULL && jwe_str_len) { token = o_strndup(jwe_str, jwe_str_len); if (split_string(token, ".", &str_array) == 5 && !o_strnullempty(str_array[0]) && !o_strnullempty(str_array[2]) && !o_strnullempty(str_array[3]) && !o_strnullempty(str_array[4])) { // Check if all elements 0, 2 and 3 are base64url encoded if (o_base64url_decode_alloc((unsigned char *)str_array[0], o_strlen(str_array[0]), &dat_header) && (o_strnullempty(str_array[1]) || o_base64url_decode((unsigned char *)str_array[1], o_strlen(str_array[1]), NULL, &cypher_key_len)) && o_base64url_decode_alloc((unsigned char *)str_array[2], o_strlen(str_array[2]), &dat_iv) && o_base64url_decode((unsigned char *)str_array[3], o_strlen(str_array[3]), NULL, &cypher_len) && o_base64url_decode((unsigned char *)str_array[4], o_strlen(str_array[4]), NULL, &tag_len)) { ret = RHN_OK; jwe->token_mode = R_JSON_MODE_COMPACT; do { // Decode header if ((j_header = json_loadb((const char *)dat_header.data, dat_header.size, JSON_DECODE_ANY, NULL)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_compact_parsen - Error json_loadb dat_header"); ret = RHN_ERROR_PARAM; break; } if (r_jwe_extract_header(jwe, j_header, parse_flags, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_compact_parsen - error extracting header params"); ret = RHN_ERROR_PARAM; break; } json_decref(jwe->j_header); jwe->j_header = json_incref(j_header); // Decode iv if (r_jwe_set_iv(jwe, dat_iv.data, dat_iv.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_compact_parsen - Error r_jwe_set_iv"); ret = RHN_ERROR; break; } o_free(jwe->header_b64url); jwe->header_b64url = (unsigned char *)o_strdup(str_array[0]); o_free(jwe->aad_b64url); jwe->aad_b64url = (unsigned char *)o_strdup(str_array[0]); o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = (unsigned char *)o_strdup(str_array[1]); o_free(jwe->iv_b64url); jwe->iv_b64url = (unsigned char *)o_strdup(str_array[2]); o_free(jwe->ciphertext_b64url); jwe->ciphertext_b64url = (unsigned char *)o_strdup(str_array[3]); o_free(jwe->auth_tag_b64url); jwe->auth_tag_b64url = (unsigned char *)o_strdup(str_array[4]); } while (0); json_decref(j_header); } else { ret = RHN_ERROR_PARAM; } o_free(dat_header.data); o_free(dat_iv.data); } else { ret = RHN_ERROR_PARAM; } free_string_array(str_array); o_free(token); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_parse_json_str(jwe_t * jwe, const char * jwe_json_str, int x5u_flags) { return r_jwe_parsen_json_str(jwe, jwe_json_str, o_strlen(jwe_json_str), x5u_flags); } int r_jwe_parsen_json_str(jwe_t * jwe, const char * jwe_json_str, size_t jwe_json_str_len, int x5u_flags) { json_t * jwe_json = NULL; int ret; jwe_json = json_loadb(jwe_json_str, jwe_json_str_len, JSON_DECODE_ANY, NULL); ret = r_jwe_parse_json_t(jwe, jwe_json, x5u_flags); json_decref(jwe_json); return ret; } int r_jwe_parse_json_t(jwe_t * jwe, json_t * jwe_json, int x5u_flags) { return r_jwe_advanced_parse_json_t(jwe, jwe_json, R_PARSE_HEADER_ALL, x5u_flags); } int r_jwe_advanced_parse_json_str(jwe_t * jwe, const char * jwe_json_str, uint32_t parse_flags, int x5u_flags) { return r_jwe_advanced_parsen_json_str(jwe, jwe_json_str, o_strlen(jwe_json_str), parse_flags, x5u_flags); } int r_jwe_advanced_parsen_json_str(jwe_t * jwe, const char * jwe_json_str, size_t jwe_json_str_len, uint32_t parse_flags, int x5u_flags) { json_t * jwe_json = NULL; int ret; jwe_json = json_loadb(jwe_json_str, jwe_json_str_len, JSON_DECODE_ANY, NULL); ret = r_jwe_advanced_parse_json_t(jwe, jwe_json, parse_flags, x5u_flags); json_decref(jwe_json); return ret; } int r_jwe_advanced_parse_json_t(jwe_t * jwe, json_t * jwe_json, uint32_t parse_flags, int x5u_flags) { int ret; size_t cypher_key_len = 0, index = 0;; json_t * j_header = NULL, * j_recipient; struct _o_datum dat_header = {0, NULL}, dat_iv = {0, NULL}; if (jwe != NULL && json_is_object(jwe_json)) { if (json_string_length(json_object_get(jwe_json, "protected")) && json_string_length(json_object_get(jwe_json, "iv")) && json_string_length(json_object_get(jwe_json, "ciphertext")) && json_string_length(json_object_get(jwe_json, "tag"))) { ret = RHN_OK; r_jwe_set_cypher_key(jwe, NULL, 0); r_jwe_set_iv(jwe, NULL, 0); r_jwe_set_aad(jwe, NULL, 0); r_jwe_set_payload(jwe, NULL, 0); o_free(jwe->header_b64url); jwe->header_b64url = NULL; o_free(jwe->encrypted_key_b64url); jwe->encrypted_key_b64url = NULL; o_free(jwe->iv_b64url); jwe->iv_b64url = NULL; o_free(jwe->ciphertext_b64url); jwe->ciphertext_b64url = NULL; o_free(jwe->auth_tag_b64url); jwe->auth_tag_b64url = NULL; o_free(jwe->aad_b64url); jwe->aad_b64url = NULL; json_decref(jwe->j_header); jwe->j_header = json_object(); json_decref(jwe->j_unprotected_header); jwe->j_unprotected_header = NULL; do { json_decref(jwe->j_json_serialization); if ((jwe->j_json_serialization = json_deep_copy(jwe_json)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error setting j_json_serialization"); ret = RHN_ERROR; break; } if (json_object_get(jwe_json, "unprotected") != NULL && r_jwe_set_full_unprotected_header_json_t(jwe, json_object_get(jwe_json, "unprotected")) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error r_jwe_set_full_unprotected_header_json_t"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode_alloc((unsigned char *)json_string_value(json_object_get(jwe_json, "protected")), json_string_length(json_object_get(jwe_json, "protected")), &dat_header)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error invalid protected base64"); ret = RHN_ERROR_PARAM; break; } if ((j_header = json_loadb((const char *)dat_header.data, dat_header.size, JSON_DECODE_ANY, NULL)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error json_loadb dat_header"); ret = RHN_ERROR_PARAM; break; } if (r_jwe_extract_header(jwe, j_header, parse_flags, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - error extracting header params"); ret = RHN_ERROR_PARAM; break; } json_decref(jwe->j_header); jwe->j_header = json_incref(j_header); // Decode iv if (!o_base64url_decode_alloc((unsigned char *)json_string_value(json_object_get(jwe_json, "iv")), json_string_length(json_object_get(jwe_json, "iv")), &dat_iv)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error o_base64url_decode_alloc iv"); ret = RHN_ERROR_PARAM; break; } if (r_jwe_set_iv(jwe, dat_iv.data, dat_iv.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error r_jwe_set_iv"); ret = RHN_ERROR; break; } jwe->header_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jwe_json, "protected"))); jwe->ciphertext_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jwe_json, "ciphertext"))); jwe->auth_tag_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jwe_json, "tag"))); jwe->aad_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jwe_json, "aad"))); } while (0); json_decref(j_header); o_free(dat_header.data); o_free(dat_iv.data); if (ret == RHN_OK) { if (json_array_size(json_object_get(jwe_json, "recipients"))) { jwe->token_mode = R_JSON_MODE_GENERAL; json_array_foreach(json_object_get(jwe_json, "recipients"), index, j_recipient) { if (!json_is_object(j_recipient)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Invalid recipient at index %zu, must be a JSON object", index); ret = RHN_ERROR_PARAM; break; } else { if (!o_base64url_decode((const unsigned char*)json_string_value(json_object_get(j_recipient, "encrypted_key")), json_string_length(json_object_get(j_recipient, "encrypted_key")), NULL, &cypher_key_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error at index %zu, invalid encrypted_key base64 %s", index); ret = RHN_ERROR_PARAM; break; } if (json_object_get(j_recipient, "header") != NULL && !json_is_object(json_object_get(j_recipient, "header"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Invalid header at index %zu, must be a JSON object", index); ret = RHN_ERROR_PARAM; break; } } } } else { jwe->token_mode = R_JSON_MODE_FLATTENED; jwe->encrypted_key_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jwe_json, "encrypted_key"))); if (json_object_get(jwe_json, "header") == NULL || r_jwe_extract_header(jwe, json_object_get(jwe_json, "header"), parse_flags, x5u_flags) == RHN_OK) { json_object_update_missing(jwe->j_header, json_object_get(jwe_json, "header")); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - error extracting header params"); ret = RHN_ERROR_PARAM; } } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error invalid content"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_parse_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } jwe_t * r_jwe_quick_parse(const char * jwe_str, uint32_t parse_flags, int x5u_flags) { return r_jwe_quick_parsen(jwe_str, o_strlen(jwe_str), parse_flags, x5u_flags); } jwe_t * r_jwe_quick_parsen(const char * jwe_str, size_t jwe_str_len, uint32_t parse_flags, int x5u_flags) { jwe_t * jwe = NULL; int ret; if (r_jwe_init(&jwe) == RHN_OK) { ret = r_jwe_advanced_parsen(jwe, jwe_str, jwe_str_len, parse_flags, x5u_flags); if (ret != RHN_OK) { r_jwe_free(jwe); jwe = NULL; } } else { r_jwe_free(jwe); jwe = NULL; } return jwe; } int r_jwe_decrypt(jwe_t * jwe, jwk_t * jwk_privkey, int x5u_flags) { int ret, res; json_t * j_recipient = NULL, * j_header, * j_cur_header; size_t index = 0, i; jwk_t * jwk = NULL, * cur_jwk = NULL; jwa_alg alg; if (jwe != NULL) { if (jwk_privkey != NULL) { jwk = r_jwk_copy(jwk_privkey); } else { if (r_jwe_get_header_str_value(jwe, "kid") != NULL) { jwk = r_jwks_get_by_kid(jwe->jwks_privkey, r_jwe_get_header_str_value(jwe, "kid")); } else if (r_jwks_size(jwe->jwks_privkey) == 1) { jwk = r_jwks_get_at(jwe->jwks_privkey, 0); } } } if (jwe != NULL) { if (jwe->token_mode == R_JSON_MODE_GENERAL) { ret = RHN_ERROR_INVALID; o_free(jwe->encrypted_key_b64url); j_header = r_jwe_get_full_header_json_t(jwe); json_array_foreach(json_object_get(jwe->j_json_serialization, "recipients"), index, j_recipient) { j_cur_header = json_deep_copy(j_header); json_object_update(j_cur_header, json_object_get(j_recipient, "header")); r_jwe_set_full_header_json_t(jwe, j_cur_header); json_decref(j_cur_header); jwe->encrypted_key_b64url = (unsigned char *)json_string_value(json_object_get(j_recipient, "encrypted_key")); alg = r_jwe_get_alg(jwe); if (json_object_get(jwe->j_unprotected_header, "alg") != NULL) { alg = r_str_to_jwa_alg(json_string_value(json_object_get(jwe->j_unprotected_header, "alg"))); } if (json_object_get(json_object_get(j_recipient, "header"), "alg") != NULL) { alg = r_str_to_jwa_alg(json_string_value(json_object_get(json_object_get(j_recipient, "header"), "alg"))); } if (alg != R_JWA_ALG_UNKNOWN && alg != R_JWA_ALG_ECDH_ES) { if (jwk_privkey != NULL) { if (r_jwk_get_property_str(jwk_privkey, "kid") == NULL || json_object_get(json_object_get(j_recipient, "header"), "kid") == NULL || 0 == o_strcmp(json_string_value(json_object_get(json_object_get(j_recipient, "header"), "kid")), r_jwk_get_property_str(jwk_privkey, "kid"))) { if ((res = _r_preform_key_decryption(jwe, alg, jwk_privkey, x5u_flags)) != RHN_ERROR_INVALID) { ret = res; break; } } } else { if (json_object_get(json_object_get(j_recipient, "header"), "kid") != NULL) { cur_jwk = r_jwks_get_by_kid(jwe->jwks_privkey, json_string_value(json_object_get(json_object_get(j_recipient, "header"), "kid"))); if ((res = _r_preform_key_decryption(jwe, alg, cur_jwk, x5u_flags)) != RHN_ERROR_INVALID) { ret = res; r_jwk_free(cur_jwk); break; } r_jwk_free(cur_jwk); } else { for (i=0; ijwks_privkey); i++) { cur_jwk = r_jwks_get_at(jwe->jwks_privkey, i); if ((res = _r_preform_key_decryption(jwe, alg, cur_jwk, x5u_flags)) != RHN_ERROR_INVALID) { ret = res; r_jwk_free(cur_jwk); break; } r_jwk_free(cur_jwk); } if (ret != RHN_ERROR_INVALID) { break; } } } cur_jwk = NULL; } else if (alg == R_JWA_ALG_ECDH_ES) { y_log_message(Y_LOG_LEVEL_DEBUG, "r_jwe_decrypt - Unsupported algorithm ECDH-ES on general serialization"); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt - Invalid alg value at index %zu: %d", index, (alg)); ret = RHN_ERROR_PARAM; } } r_jwe_set_full_header_json_t(jwe, j_header); json_decref(j_header); jwe->encrypted_key_b64url = NULL; if (ret == RHN_OK) { ret = r_jwe_decrypt_payload(jwe); } } else { j_header = r_jwe_get_full_header_json_t(jwe); j_cur_header = json_deep_copy(j_header); json_object_update(j_cur_header, json_object_get(j_recipient, "header")); if (jwe->j_unprotected_header != NULL) { json_object_update(j_cur_header, jwe->j_unprotected_header); } r_jwe_set_full_header_json_t(jwe, j_cur_header); json_decref(j_cur_header); if ((res = r_jwe_decrypt_key(jwe, jwk, x5u_flags)) == RHN_OK && (res = r_jwe_decrypt_payload(jwe)) == RHN_OK) { ret = RHN_OK; } else { if (res != RHN_ERROR_INVALID) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_decrypt - Error decrypting data"); } ret = res; } r_jwe_set_full_header_json_t(jwe, j_header); json_decref(j_header); } } else { ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); return ret; } char * r_jwe_serialize(jwe_t * jwe, jwk_t * jwk_pubkey, int x5u_flags) { char * jwe_str = NULL; int res = RHN_OK; unsigned int bits = 0; unsigned char * key = NULL; size_t key_len = 0; if (jwk_pubkey != NULL && jwe != NULL && jwe->alg == R_JWA_ALG_DIR) { if (r_jwk_key_type(jwk_pubkey, &bits, x5u_flags) & R_KEY_TYPE_SYMMETRIC && bits == _r_get_key_size(jwe->enc)*8) { key_len = (size_t)(bits/8); if ((key = o_malloc(key_len+4)) != NULL) { if (r_jwk_export_to_symmetric_key(jwk_pubkey, key, &key_len) == RHN_OK) { res = r_jwe_set_cypher_key(jwe, key, key_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error r_jwk_export_to_symmetric_key"); res = RHN_ERROR_MEMORY; } o_free(key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error allocating resources for key"); res = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error invalid key type"); res = RHN_ERROR_PARAM; } } else { res = RHN_OK; } if (res == RHN_OK) { if (jwe->key == NULL || !jwe->key_len) { if (r_jwe_generate_cypher_key(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error r_jwe_generate_cypher_key"); res = RHN_ERROR; } } if (jwe->iv == NULL || !jwe->iv_len) { if (r_jwe_generate_iv(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error r_jwe_generate_iv"); res = RHN_ERROR; } } } if (res == RHN_OK && r_jwe_set_alg_header(jwe, jwe->j_header) == RHN_OK && r_jwe_encrypt_key(jwe, jwk_pubkey, x5u_flags) == RHN_OK && r_jwe_encrypt_payload(jwe) == RHN_OK) { jwe_str = msprintf("%s.%s.%s.%s.%s", jwe->header_b64url, jwe->encrypted_key_b64url!=NULL?(const char *)jwe->encrypted_key_b64url:"", jwe->iv_b64url, jwe->ciphertext_b64url, jwe->auth_tag_b64url); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize - Error input parameters"); } return jwe_str; } char * r_jwe_serialize_json_str(jwe_t * jwe, jwks_t * jwks_pubkey, int x5u_flags, int mode) { json_t * j_result = r_jwe_serialize_json_t(jwe, jwks_pubkey, x5u_flags, mode); char * str_result = json_dumps(j_result, JSON_COMPACT); json_decref(j_result); return str_result; } json_t * r_jwe_serialize_json_t(jwe_t * jwe, jwks_t * jwks_pubkey, int x5u_flags, int mode) { json_t * j_return = NULL, * j_result; jwk_t * jwk = NULL; jwa_alg alg = R_JWA_ALG_NONE; const char * kid = NULL; size_t i = 0; int res = RHN_OK; if (jwks_pubkey == NULL) { jwks_pubkey = jwe->jwks_pubkey; } if (jwe != NULL && r_jwks_size(jwks_pubkey)) { jwe->token_mode = mode; if (mode == R_JSON_MODE_FLATTENED) { if ((kid = r_jwe_get_header_str_value(jwe, "kid")) != NULL) { jwk = r_jwks_get_by_kid(jwks_pubkey, kid); } else { jwk = r_jwks_get_at(jwks_pubkey, 0); kid = r_jwk_get_property_str(jwk, "kid"); } alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk, "alg")); if (alg == R_JWA_ALG_UNKNOWN) { alg = jwe->alg; } if (jwe->key == NULL || !jwe->key_len) { if (r_jwe_generate_cypher_key(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error r_jwe_generate_cypher_key"); res = RHN_ERROR; } } if (jwe->iv == NULL || !jwe->iv_len) { if (r_jwe_generate_iv(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error r_jwe_generate_iv"); res = RHN_ERROR; } } if (res == RHN_OK) { if ((j_result = r_jwe_perform_key_encryption(jwe, alg, jwk, x5u_flags, &res)) != NULL) { if (r_jwe_encrypt_payload(jwe) == RHN_OK) { if ((kid = r_jwe_get_header_str_value(jwe, "kid")) == NULL) { kid = r_jwk_get_property_str(jwk, "kid"); } j_return = json_pack("{ss sO* ss ss ss sO*}", "protected", jwe->header_b64url, "encrypted_key", json_object_get(j_result, "encrypted_key"), "iv", jwe->iv_b64url, "ciphertext", jwe->ciphertext_b64url, "tag", jwe->auth_tag_b64url, "header", json_object_get(j_result, "header")); if (jwe->aad_b64url != NULL) { json_object_set_new(j_return, "aad", json_string((const char *)jwe->aad_b64url)); } if (jwe->j_unprotected_header != NULL) { json_object_set_new(j_return, "unprotected", json_deep_copy(jwe->j_unprotected_header)); } if (kid != NULL) { json_object_set_new(json_object_get(j_return, "header"), "kid", json_string(kid)); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error input parameters"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error invalid encryption key"); } json_decref(j_result); } r_jwk_free(jwk); } else if (mode == R_JSON_MODE_GENERAL) { if (jwe->key == NULL || !jwe->key_len) { if (r_jwe_generate_cypher_key(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error r_jwe_generate_cypher_key"); res = RHN_ERROR; } } if (jwe->iv == NULL || !jwe->iv_len) { if (r_jwe_generate_iv(jwe) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error r_jwe_generate_iv"); res = RHN_ERROR; } } if (res == RHN_OK && r_jwe_encrypt_payload(jwe) == RHN_OK) { j_return = json_pack("{ss ss ss ss s[]}", "protected", jwe->header_b64url, "iv", jwe->iv_b64url, "ciphertext", jwe->ciphertext_b64url, "tag", jwe->auth_tag_b64url, "recipients"); if (jwe->aad_b64url != NULL) { json_object_set_new(j_return, "aad", json_string((const char *)jwe->aad_b64url)); } if (jwe->j_unprotected_header != NULL) { json_object_set_new(j_return, "unprotected", json_deep_copy(jwe->j_unprotected_header)); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error input parameters"); } //r_jwe_set_header_str_value(jwe, "alg", NULL); for (i=0; ij_header, "kid") == NULL && json_object_get(jwe->j_unprotected_header, "kid") == NULL) { json_object_set_new(json_object_get(j_result, "header"), "kid", json_string(r_jwk_get_property_str(jwk, "kid"))); } json_array_append(json_object_get(j_return, "recipients"), j_result); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error invalid encryption key at index %zu", i); } json_decref(j_result); } else if (alg == R_JWA_ALG_ECDH_ES) { y_log_message(Y_LOG_LEVEL_DEBUG, "r_jwe_serialize_json_t - Unsupported algorithm for JWE with multiple recipients"); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error invalid encryption algorithm at index %zu", i); } r_jwk_free(jwk); } if (!json_array_size(json_object_get(j_return, "recipients"))) { json_decref(j_return); j_return = NULL; } } json_decref(jwe->j_json_serialization); jwe->j_json_serialization = json_deep_copy(j_return); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_serialize_json_t - Error input parameters"); } return j_return; } int r_jwe_set_full_header_json_t(jwe_t * jwe, json_t * j_header) { int ret = RHN_OK; jwa_alg alg; jwa_enc enc; if (jwe != NULL && json_is_object(j_header)) { if (json_object_get(j_header, "alg") != NULL) { if ((alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg")))) != R_JWA_ALG_UNKNOWN) { jwe->alg = alg; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_header_json_t - Error invalid alg parameter"); ret = RHN_ERROR_PARAM; } } if (json_object_get(j_header, "enc") != NULL) { if ((enc = r_str_to_jwa_enc(json_string_value(json_object_get(j_header, "enc")))) != R_JWA_ENC_UNKNOWN) { jwe->enc = enc; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_header_json_t - Error invalid enc parameter"); ret = RHN_ERROR_PARAM; } } if (ret == RHN_OK) { json_decref(jwe->j_header); if ((jwe->j_header = json_deep_copy(j_header)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_header_json_t - Error setting header"); ret = RHN_ERROR_MEMORY; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_header_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_set_full_header_json_str(jwe_t * jwe, const char * str_header) { int ret; json_t * j_header = json_loads(str_header, JSON_DECODE_ANY, NULL); ret = r_jwe_set_full_header_json_t(jwe, j_header); json_decref(j_header); return ret; } int r_jwe_set_full_unprotected_header_json_t(jwe_t * jwe, json_t * j_unprotected_header) { int ret = RHN_OK; if (jwe != NULL && json_is_object(j_unprotected_header)) { json_decref(jwe->j_unprotected_header); if ((jwe->j_unprotected_header = json_deep_copy(j_unprotected_header)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_unprotected_header_json_t - Error setting header"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_full_unprotected_header_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwe_set_full_unprotected_header_json_str(jwe_t * jwe, const char * str_unprotected_header) { int ret; json_t * j_unprotected_header = json_loads(str_unprotected_header, JSON_DECODE_ANY, NULL); ret = r_jwe_set_full_unprotected_header_json_t(jwe, j_unprotected_header); json_decref(j_unprotected_header); return ret; } int r_jwe_set_properties(jwe_t * jwe, ...) { rhn_opt option; int ret = RHN_OK; int i_value; rhn_int_t r_value; unsigned int ui_value; const char * str_key, * str_value; json_t * j_value; const unsigned char * ustr_value; size_t size_value; jwk_t * jwk; jwks_t * jwks; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; va_list vl; if (jwe != NULL) { va_start(vl, jwe); for (option = va_arg(vl, rhn_opt); option != RHN_OPT_NONE && ret == RHN_OK; option = va_arg(vl, rhn_opt)) { switch (option) { case RHN_OPT_HEADER_INT_VALUE: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); ret = r_jwe_set_header_int_value(jwe, str_key, (rhn_int_t)i_value); break; case RHN_OPT_HEADER_RHN_INT_VALUE: str_key = va_arg(vl, const char *); r_value = va_arg(vl, rhn_int_t); ret = r_jwe_set_header_int_value(jwe, str_key, r_value); break; case RHN_OPT_HEADER_STR_VALUE: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); ret = r_jwe_set_header_str_value(jwe, str_key, str_value); break; case RHN_OPT_HEADER_JSON_T_VALUE: str_key = va_arg(vl, const char *); j_value = va_arg(vl, json_t *); ret = r_jwe_set_header_json_t_value(jwe, str_key, j_value); break; case RHN_OPT_HEADER_FULL_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwe_set_full_header_json_t(jwe, j_value); break; case RHN_OPT_HEADER_FULL_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwe_set_full_header_json_str(jwe, str_value); break; case RHN_OPT_UN_HEADER_FULL_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwe_set_full_unprotected_header_json_t(jwe, j_value); break; case RHN_OPT_UN_HEADER_FULL_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwe_set_full_unprotected_header_json_str(jwe, str_value); break; case RHN_OPT_PAYLOAD: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_set_payload(jwe, ustr_value, size_value); break; case RHN_OPT_ENC_ALG: ui_value = va_arg(vl, unsigned int); ret = r_jwe_set_alg(jwe, (jwa_alg)ui_value); break; case RHN_OPT_ENC: ui_value = va_arg(vl, unsigned int); ret = r_jwe_set_enc(jwe, (jwa_enc)ui_value); break; case RHN_OPT_CIPHER_KEY: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_set_cypher_key(jwe, ustr_value, size_value); break; case RHN_OPT_IV: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_set_iv(jwe, ustr_value, size_value); break; case RHN_OPT_AAD: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_set_aad(jwe, ustr_value, size_value); break; case RHN_OPT_ENCRYPT_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwe_add_keys(jwe, NULL, jwk); break; case RHN_OPT_ENCRYPT_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwe_add_jwks(jwe, NULL, jwks); break; case RHN_OPT_ENCRYPT_KEY_GNUTLS: pubkey = va_arg(vl, gnutls_pubkey_t); ret = r_jwe_add_keys_gnutls(jwe, NULL, pubkey); break; case RHN_OPT_ENCRYPT_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwe_add_keys_json_t(jwe, NULL, j_value); break; case RHN_OPT_ENCRYPT_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwe_add_keys_json_str(jwe, NULL, str_value); break; case RHN_OPT_ENCRYPT_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_add_keys_pem_der(jwe, (int)ui_value, NULL, 0, ustr_value, size_value); break; case RHN_OPT_DECRYPT_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwe_add_keys(jwe, jwk, NULL); break; case RHN_OPT_DECRYPT_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwe_add_jwks(jwe, jwks, NULL); break; case RHN_OPT_DECRYPT_KEY_GNUTLS: privkey = va_arg(vl, gnutls_privkey_t); ret = r_jwe_add_keys_gnutls(jwe, privkey, NULL); break; case RHN_OPT_DECRYPT_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwe_add_keys_json_t(jwe, j_value, NULL); break; case RHN_OPT_DECRYPT_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwe_add_keys_json_str(jwe, str_value, NULL); break; case RHN_OPT_DECRYPT_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwe_add_keys_pem_der(jwe, (int)ui_value, ustr_value, size_value, NULL, 0); break; default: ret = RHN_ERROR_PARAM; break; } } va_end(vl); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwe_set_properties - Error input parameter"); ret = RHN_ERROR_PARAM; } return ret; } rhonabwy-1.1.13/src/jwk.c000066400000000000000000003704041452472117100151700ustar00rootroot00000000000000/** * * Rhonabwy JSON Web Key (JWK) library * * jwk.c: functions definitions * * Copyright 2020-2022 Nicolas Mora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include #include #include #include #include #define RHN_PEM_HEADER_CERT "-----BEGIN CERTIFICATE-----" #define RHN_PEM_HEADER_PUBKEY "-----BEGIN PUBLIC KEY-----" #define RHN_PEM_HEADER_PRIVKEY "-----BEGIN PRIVATE KEY-----" #define RHN_PEM_HEADER_EC_PRIVKEY "-----BEGIN EC PRIVATE KEY-----" #define RHN_PEM_HEADER_RSA_PRIVKEY "-----BEGIN RSA PRIVATE KEY-----" #define RHN_PEM_HEADER_UNKNOWN_PRIVKEY "-----BEGIN UNKNOWN-----" int _r_get_http_content(const char * url, int x5u_flags, const char * expected_content_type, struct _o_datum * datum); #if NETTLE_VERSION_NUMBER >= 0x030600 #include #include #endif int r_jwk_init(jwk_t ** jwk) { int ret; if (jwk != NULL) { *jwk = json_object(); ret = (*jwk!=NULL)?RHN_OK:RHN_ERROR_MEMORY; } else { ret = RHN_ERROR_PARAM; } return ret; } void r_jwk_free(jwk_t * jwk) { if (jwk != NULL) { json_decref(jwk); } } int r_jwk_is_valid(jwk_t * jwk) { int ret = RHN_OK, has_privkey_parameters = 0, type_x5c, is_x5_key = 0; json_t * j_element = NULL; const char * n, * e, * x, * y; size_t index = 0, b64dec_len = 0; jwk_t * jwk_x5c = NULL; gnutls_pubkey_t pubkey = NULL; gnutls_x509_crt_t crt = NULL; gnutls_datum_t data; struct _o_datum dat = {0, NULL}; if (jwk != NULL) { if (json_is_object(jwk)) { // JWK parameters if (json_object_get(jwk, "x5u") != NULL) { if (!json_is_string(json_object_get(jwk, "x5u")) || o_strncasecmp("https://", json_string_value(json_object_get(jwk, "x5u")), o_strlen("https://"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5u"); ret = RHN_ERROR_PARAM; } is_x5_key = 1; } if (json_object_get(jwk, "x5c") != NULL) { is_x5_key = 1; if (!json_is_array(json_object_get(jwk, "x5c"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c"); ret = RHN_ERROR_PARAM; } else { json_array_foreach(json_object_get(jwk, "x5c"), index, j_element) { if (!json_string_length(j_element) || !o_base64_decode((const unsigned char *)json_string_value(j_element), json_string_length(j_element), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c"); ret = RHN_ERROR_PARAM; } } if ((j_element = json_array_get(json_object_get(jwk, "x5c"), 0)) != NULL) { if (json_string_length(j_element) && o_base64_decode_alloc((const unsigned char *)json_string_value(j_element), json_string_length(j_element), &dat)) { if (!gnutls_x509_crt_init(&crt)) { if (!gnutls_pubkey_init(&pubkey)) { data.data = dat.data; data.size = (unsigned int)dat.size; if (!gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER)) { if (gnutls_pubkey_import_x509(pubkey, crt, 0)) { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Error gnutls_pubkey_import_x509"); ret = RHN_ERROR_PARAM; } } else { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Error gnutls_pubkey_import"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Error gnutls_pubkey_init rsa"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Error gnutls_x509_crt_init"); ret = RHN_ERROR; } gnutls_x509_crt_deinit(crt); if (pubkey != NULL) { if (r_jwk_init(&jwk_x5c) == RHN_OK) { if (r_jwk_import_from_gnutls_pubkey(jwk_x5c, pubkey) == RHN_OK) { type_x5c = r_jwk_key_type(jwk_x5c, NULL, 0); if (type_x5c & R_KEY_TYPE_RSA) { if (0 != o_strcmp("RSA", r_jwk_get_property_str(jwk, "kty"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c key type"); ret = RHN_ERROR_PARAM; } if ((n = r_jwk_get_property_str(jwk, "n")) != NULL && (e = r_jwk_get_property_str(jwk, "e")) != NULL) { if (0 != o_strcmp(n, r_jwk_get_property_str(jwk_x5c, "n")) || 0 != o_strcmp(e, r_jwk_get_property_str(jwk_x5c, "e"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c leaf rsa parameters"); } } } else if (type_x5c & R_KEY_TYPE_EC) { if (0 != o_strcmp("EC", r_jwk_get_property_str(jwk, "kty")) || 0 != o_strcmp(r_jwk_get_property_str(jwk, "crv"), r_jwk_get_property_str(jwk_x5c, "crv"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c key type"); ret = RHN_ERROR_PARAM; } if ((x = r_jwk_get_property_str(jwk, "x")) != NULL && (y = r_jwk_get_property_str(jwk, "y")) != NULL) { if (0 != o_strcmp(x, r_jwk_get_property_str(jwk_x5c, "x")) || 0 != o_strcmp(y, r_jwk_get_property_str(jwk_x5c, "y"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c leaf ec parameters"); } } } else if (type_x5c & R_KEY_TYPE_EDDSA) { if (0 != o_strcmp("OKP", r_jwk_get_property_str(jwk, "kty")) || 0 != o_strcmp(r_jwk_get_property_str(jwk, "crv"), r_jwk_get_property_str(jwk_x5c, "crv"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c key type"); ret = RHN_ERROR_PARAM; } if ((x = r_jwk_get_property_str(jwk, "x")) != NULL) { if (0 != o_strcmp(x, r_jwk_get_property_str(jwk_x5c, "x"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c leaf ec parameters"); } } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5c leaf"); ret = RHN_ERROR_PARAM; } } r_jwk_free(jwk_x5c); gnutls_pubkey_deinit(pubkey); } o_free(dat.data); } } } } if (!json_string_length(json_object_get(jwk, "kty"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Missing kty"); ret = RHN_ERROR_PARAM; } if (json_object_get(jwk, "use") != NULL && !json_is_string(json_object_get(jwk, "use"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid use"); ret = RHN_ERROR_PARAM; } if (json_object_get(jwk, "key_ops") != NULL) { if (!json_is_array(json_object_get(jwk, "key_ops"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid key_ops"); ret = RHN_ERROR_PARAM; } else { json_array_foreach(json_object_get(jwk, "key_ops"), index, j_element) { if (!json_string_length(j_element)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid key_ops"); ret = RHN_ERROR_PARAM; } } } } if (json_object_get(jwk, "alg") != NULL) { if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "oct")) { if (r_str_to_jwa_enc(json_string_value(json_object_get(jwk, "alg"))) == R_JWA_ENC_UNKNOWN && r_str_to_jwa_alg(json_string_value(json_object_get(jwk, "alg"))) == R_JWA_ALG_UNKNOWN) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid oct alg value: '%s'", json_string_value(json_object_get(jwk, "alg"))); ret = RHN_ERROR_PARAM; } } else { if (r_str_to_jwa_alg(json_string_value(json_object_get(jwk, "alg"))) == R_JWA_ALG_UNKNOWN) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid alg alg value: '%s'", json_string_value(json_object_get(jwk, "alg"))); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "kid") != NULL && !json_is_string(json_object_get(jwk, "kid"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid kid"); ret = RHN_ERROR_PARAM; } if (json_object_get(jwk, "x5t") != NULL && !json_is_string(json_object_get(jwk, "x5t"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5t"); ret = RHN_ERROR_PARAM; } if (json_object_get(jwk, "x5t#S256") != NULL && !json_is_string(json_object_get(jwk, "x5t#S256"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x5t#S256"); ret = RHN_ERROR_PARAM; } // JWA parameters validation if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "EC")) { if (json_object_get(jwk, "crv") != NULL) { if (0 != o_strcmp("P-256", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("P-384", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("P-521", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("secp256k1", json_string_value(json_object_get(jwk, "crv")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid EC crv value: '%s'", json_string_value(json_object_get(jwk, "crv"))); ret = RHN_ERROR_PARAM; } } if (!is_x5_key && !json_string_length(json_object_get(jwk, "x"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x"); ret = RHN_ERROR_PARAM; } else if (json_string_length(json_object_get(jwk, "x"))) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x format"); ret = RHN_ERROR_PARAM; } } if (!is_x5_key && !json_string_length(json_object_get(jwk, "y"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid y"); ret = RHN_ERROR_PARAM; } else if (json_string_length(json_object_get(jwk, "y"))) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "y")), json_string_length(json_object_get(jwk, "y")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid y format"); ret = RHN_ERROR_PARAM; } } if (json_object_get(jwk, "d") != NULL) { if (!json_string_length(json_object_get(jwk, "d"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d"); ret = RHN_ERROR_PARAM; } else { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d format"); ret = RHN_ERROR_PARAM; } has_privkey_parameters = 1; } } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "OKP")) { if (json_object_get(jwk, "crv")) { if (0 != o_strcmp("Ed25519", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("Ed448", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("X25519", json_string_value(json_object_get(jwk, "crv"))) && 0 != o_strcmp("X448", json_string_value(json_object_get(jwk, "crv")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid OKP crv value: '%s'", json_string_value(json_object_get(jwk, "crv"))); ret = RHN_ERROR_PARAM; } } if (!is_x5_key && !json_string_length(json_object_get(jwk, "x"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x"); ret = RHN_ERROR_PARAM; } else if (json_string_length(json_object_get(jwk, "x"))) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid x format"); ret = RHN_ERROR_PARAM; } } if (json_object_get(jwk, "d") != NULL) { if (!json_string_length(json_object_get(jwk, "d"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d"); ret = RHN_ERROR_PARAM; } else { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d format"); ret = RHN_ERROR_PARAM; } has_privkey_parameters = 1; } } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "RSA")) { if (!is_x5_key && !json_string_length(json_object_get(jwk, "n"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid n"); ret = RHN_ERROR_PARAM; } else if (json_string_length(json_object_get(jwk, "n"))) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "n")), json_string_length(json_object_get(jwk, "n")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid n format"); ret = RHN_ERROR_PARAM; } } if (!is_x5_key && !json_string_length(json_object_get(jwk, "e"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid e"); ret = RHN_ERROR_PARAM; } else if (json_string_length(json_object_get(jwk, "e"))) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "e")), json_string_length(json_object_get(jwk, "e")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid e format"); ret = RHN_ERROR_PARAM; } } if (json_object_get(jwk, "d") != NULL) { if (!json_string_length(json_object_get(jwk, "d"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d"); ret = RHN_ERROR_PARAM; } else { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d format"); ret = RHN_ERROR_PARAM; } } has_privkey_parameters = 1; } if (json_object_get(jwk, "p") != NULL) { if (!json_string_length(json_object_get(jwk, "p"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid p"); ret = RHN_ERROR_PARAM; } else if (has_privkey_parameters) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "p")), json_string_length(json_object_get(jwk, "p")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid d format"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "q") != NULL) { if (!json_string_length(json_object_get(jwk, "q"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid q"); ret = RHN_ERROR_PARAM; } else if (has_privkey_parameters) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "q")), json_string_length(json_object_get(jwk, "q")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid q format"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "dp") != NULL) { if (!json_string_length(json_object_get(jwk, "dp"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid dp"); ret = RHN_ERROR_PARAM; } else if (has_privkey_parameters) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "dp")), json_string_length(json_object_get(jwk, "dp")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid dp format"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "dq") != NULL) { if (!json_string_length(json_object_get(jwk, "dq"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid dq"); ret = RHN_ERROR_PARAM; } else if (has_privkey_parameters) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "dq")), json_string_length(json_object_get(jwk, "dq")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid dq format"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "qi") != NULL) { if (!json_string_length(json_object_get(jwk, "qi"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid qi"); ret = RHN_ERROR_PARAM; } else if (has_privkey_parameters) { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "qi")), json_string_length(json_object_get(jwk, "qi")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid qi format"); ret = RHN_ERROR_PARAM; } } } if (json_object_get(jwk, "oth") != NULL) { ret = RHN_ERROR_UNSUPPORTED; } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "oct")) { if (!json_string_length(json_object_get(jwk, "k"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid k"); ret = RHN_ERROR_PARAM; } else { if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "k")), json_string_length(json_object_get(jwk, "k")), NULL, &b64dec_len) || !b64dec_len) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid k format"); ret = RHN_ERROR_PARAM; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid - Invalid kty"); ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_is_valid_x5u(jwk_t * jwk, int x5u_flags) { int ret, type, type_x5u; jwk_t * jwk_x5u = NULL; if (r_jwk_is_valid(jwk) == RHN_OK && r_jwk_get_property_str(jwk, "x5u") != NULL) { type = r_jwk_key_type(jwk, NULL, x5u_flags); if (type & R_KEY_TYPE_RSA) { if (r_jwk_init(&jwk_x5u) == RHN_OK) { if (r_jwk_import_from_x5u(jwk_x5u, x5u_flags, r_jwk_get_property_str(jwk, "x5u")) == RHN_OK) { type_x5u = r_jwk_key_type(jwk_x5u, NULL, x5u_flags); if (type_x5u == type) { ret = RHN_OK; if (r_jwk_get_property_str(jwk, "n") != NULL && r_jwk_get_property_str(jwk, "e") != NULL && (0 != o_strcmp(r_jwk_get_property_str(jwk, "n"), r_jwk_get_property_str(jwk_x5u, "n")) || 0 != o_strcmp(r_jwk_get_property_str(jwk, "e"), r_jwk_get_property_str(jwk_x5u, "e")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key parameters (rsa)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key type (rsa expected)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_import_from_x5u (rsa)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_init (rsa)"); ret = RHN_ERROR; } r_jwk_free(jwk_x5u); } else if (type & R_KEY_TYPE_EC) { if (r_jwk_init(&jwk_x5u) == RHN_OK) { if (r_jwk_import_from_x5u(jwk_x5u, x5u_flags, r_jwk_get_property_str(jwk, "x5u")) == RHN_OK) { type_x5u = r_jwk_key_type(jwk_x5u, NULL, x5u_flags); if (type_x5u == type) { ret = RHN_OK; if (json_object_get(jwk, "x") != NULL && json_object_get(jwk, "y") != NULL && (0 != o_strcmp(r_jwk_get_property_str(jwk, "x"), r_jwk_get_property_str(jwk_x5u, "x")) || 0 != o_strcmp(r_jwk_get_property_str(jwk, "y"), r_jwk_get_property_str(jwk_x5u, "y")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key parameters (ec)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key type (ec expected)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_import_from_x5u (ec)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_init (ec)"); ret = RHN_ERROR; } r_jwk_free(jwk_x5u); } else if (type & R_KEY_TYPE_EDDSA) { if (r_jwk_init(&jwk_x5u) == RHN_OK) { if (r_jwk_import_from_x5u(jwk_x5u, x5u_flags, r_jwk_get_property_str(jwk, "x5u")) == RHN_OK) { type_x5u = r_jwk_key_type(jwk_x5u, NULL, x5u_flags); if (type_x5u == type) { ret = RHN_OK; if (json_object_get(jwk, "x") != NULL && (0 != o_strcmp(r_jwk_get_property_str(jwk, "x"), r_jwk_get_property_str(jwk_x5u, "x")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key parameters (eddsa)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error invalid x5u key type (eddsa expected)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_import_from_x5u (eddsa)"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_is_valid_x5u - Error r_jwk_init (eddsa)"); ret = RHN_ERROR; } r_jwk_free(jwk_x5u); } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_generate_key_pair(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int type, unsigned int bits, const char * kid) { int ret; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; #if GNUTLS_VERSION_NUMBER >= 0x030400 int res; unsigned int ec_bits = 0; gnutls_pk_algorithm_t alg = GNUTLS_PK_UNKNOWN; #endif #if NETTLE_VERSION_NUMBER >= 0x030600 unsigned char x_ecdh[CURVE448_SIZE] = {0}, d_ecdh[CURVE448_SIZE] = {0}, x_ecdh_b64[CURVE448_SIZE*2]; const unsigned char * d_b64 = NULL; size_t d_ecdh_size = CURVE448_SIZE, x_ecdh_b64_size = 0; #endif if (jwk_privkey != NULL && jwk_pubkey != NULL && (type == R_KEY_TYPE_RSA || type == R_KEY_TYPE_EC || type == R_KEY_TYPE_EDDSA || type == R_KEY_TYPE_ECDH) && bits) { if (!gnutls_privkey_init(&privkey) && !gnutls_pubkey_init(&pubkey)) { if (type == R_KEY_TYPE_RSA) { if (!gnutls_privkey_generate(privkey, GNUTLS_PK_RSA, bits, 0)) { if (!gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_DATA_ENCIPHERMENT, 0)) { if (r_jwk_import_from_gnutls_privkey(jwk_privkey, privkey) == RHN_OK) { if (r_jwk_import_from_gnutls_pubkey(jwk_pubkey, pubkey) == RHN_OK) { if (!o_strnullempty(kid)) { r_jwk_set_property_str(jwk_privkey, "kid", kid); r_jwk_set_property_str(jwk_pubkey, "kid", kid); } ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error r_jwk_import_from_gnutls_pubkey RSA"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error r_jwk_import_from_gnutls_privkey RSA"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error gnutls_pubkey_import_privkey RSA"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error gnutls_privkey_generate RSA"); ret = RHN_ERROR; } #if GNUTLS_VERSION_NUMBER >= 0x030400 } else if (type == R_KEY_TYPE_EC || type == R_KEY_TYPE_EDDSA || type == R_KEY_TYPE_ECDH) { if (type == R_KEY_TYPE_EC) { if (bits == 256) { ec_bits = GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP256R1); alg = GNUTLS_PK_ECDSA; } else if (bits == 384) { ec_bits = GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP384R1); alg = GNUTLS_PK_ECDSA; } else if (bits == 521) { ec_bits = GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_SECP521R1); alg = GNUTLS_PK_ECDSA; } #if GNUTLS_VERSION_NUMBER >= 0x030600 } else if (type == R_KEY_TYPE_EDDSA || type == R_KEY_TYPE_ECDH) { if (bits == 256) { ec_bits = GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_ED25519); alg = GNUTLS_PK_EDDSA_ED25519; #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (bits == 448) { ec_bits = GNUTLS_CURVE_TO_BITS(GNUTLS_ECC_CURVE_ED448); alg = GNUTLS_PK_EDDSA_ED448; #endif } #endif } if (ec_bits) { if (!(res = gnutls_privkey_generate(privkey, alg, ec_bits, 0))) { if (!gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_DATA_ENCIPHERMENT, 0)) { if (r_jwk_import_from_gnutls_privkey(jwk_privkey, privkey) == RHN_OK) { if (r_jwk_import_from_gnutls_pubkey(jwk_pubkey, pubkey) == RHN_OK) { if (!o_strnullempty(kid)) { r_jwk_set_property_str(jwk_privkey, "kid", kid); r_jwk_set_property_str(jwk_pubkey, "kid", kid); } #if NETTLE_VERSION_NUMBER >= 0x030600 if (type == R_KEY_TYPE_ECDH) { d_b64 = (const unsigned char *)r_jwk_get_property_str(jwk_privkey, "d"); if (o_base64url_decode(d_b64, o_strlen((const char *)d_b64), d_ecdh, &d_ecdh_size)) { ret = RHN_OK; if (bits == 256) { r_jwk_set_property_str(jwk_privkey, "crv", "X25519"); r_jwk_set_property_str(jwk_pubkey, "crv", "X25519"); curve25519_mul_g(x_ecdh, d_ecdh); #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (bits == 448) { r_jwk_set_property_str(jwk_privkey, "crv", "X448"); r_jwk_set_property_str(jwk_pubkey, "crv", "X448"); curve448_mul_g(x_ecdh, d_ecdh); #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error unsupported curve"); ret = RHN_ERROR; } if (ret == RHN_OK) { if (o_base64url_encode(x_ecdh, bits==256?CURVE25519_SIZE:CURVE448_SIZE, x_ecdh_b64, &x_ecdh_b64_size)) { x_ecdh_b64[x_ecdh_b64_size] = '\0'; r_jwk_set_property_str(jwk_pubkey, "x", (const char *)x_ecdh_b64); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error o_base64url_encode ECDH"); ret = RHN_ERROR; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error o_base64url_decode ECDH"); ret = RHN_ERROR; } } else { ret = RHN_OK; } #else ret = RHN_OK; #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error r_jwk_import_from_gnutls_pubkey ECC"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error r_jwk_import_from_gnutls_privkey ECC"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error gnutls_pubkey_import_privkey ECC"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error gnutls_privkey_generate ECC %d", res); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error curve length"); ret = RHN_ERROR_PARAM; } #endif // GNUTLS_VERSION_NUMBER >= 0x030500 } else { ret = RHN_ERROR_PARAM; } gnutls_privkey_deinit(privkey); gnutls_pubkey_deinit(pubkey); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error gnutls_privkey_init"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_generate_key_pair - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_key_type(jwk_t * jwk, unsigned int * bits, int x5u_flags) { gnutls_x509_crt_t crt = NULL; gnutls_datum_t data; int ret = R_KEY_TYPE_NONE, pk_alg; size_t k_len = 0; int bits_set = 0, has_values = 0; struct _o_datum dat = {0, NULL}, x5u_datum = {0, NULL}; if (r_jwk_is_valid(jwk) == RHN_OK) { if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "RSA")) { ret = R_KEY_TYPE_RSA; if (json_object_get(jwk, "n")) { has_values = 1; } if (json_object_get(jwk, "d")) { ret |= R_KEY_TYPE_PRIVATE; } else { ret |= R_KEY_TYPE_PUBLIC; } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "EC")) { ret = R_KEY_TYPE_EC; if (json_object_get(jwk, "x")) { has_values = 1; } if (json_object_get(jwk, "d") != NULL) { ret |= R_KEY_TYPE_PRIVATE; } else { ret |= R_KEY_TYPE_PUBLIC; } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "OKP")) { if (0 == o_strcmp("X25519", json_string_value(json_object_get(jwk, "crv"))) || 0 == o_strcmp("X448", json_string_value(json_object_get(jwk, "crv")))) { ret = R_KEY_TYPE_ECDH; } else if (0 == o_strcmp("Ed25519", json_string_value(json_object_get(jwk, "crv"))) || 0 == o_strcmp("Ed448", json_string_value(json_object_get(jwk, "crv")))) { ret = R_KEY_TYPE_EDDSA; } if (json_object_get(jwk, "x")) { has_values = 1; } if (json_object_get(jwk, "d") != NULL) { ret |= R_KEY_TYPE_PRIVATE; } else { ret |= R_KEY_TYPE_PUBLIC; } } else if (0 == o_strcmp(json_string_value(json_object_get(jwk, "kty")), "oct")) { ret = R_KEY_TYPE_HMAC|R_KEY_TYPE_SYMMETRIC; has_values = 1; } if (!has_values) { if (json_object_get(jwk, "x5c") != NULL) { if (o_base64_decode_alloc((unsigned char *)json_string_value(json_array_get(json_object_get(jwk, "x5c"), 0)), json_string_length(json_array_get(json_object_get(jwk, "x5c"), 0)), &dat)) { data.data = dat.data; data.size = (unsigned int)dat.size; if (!gnutls_x509_crt_init(&crt)) { if (!gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER)) { pk_alg = gnutls_x509_crt_get_pk_algorithm(crt, bits); bits_set = 1; if ((ret&R_KEY_TYPE_RSA)) { if (pk_alg != GNUTLS_PK_RSA) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Invalid x5c type, expected RSA"); ret = R_KEY_TYPE_NONE; } #if GNUTLS_VERSION_NUMBER >= 0x030600 } else if ((ret&R_KEY_TYPE_EC)) { if (pk_alg != GNUTLS_PK_ECDSA) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Invalid x5c type, expected EC"); ret = R_KEY_TYPE_NONE; } } else if ((ret&R_KEY_TYPE_EDDSA)) { #if GNUTLS_VERSION_NUMBER >= 0x03060e if (pk_alg != GNUTLS_PK_EDDSA_ED25519 && pk_alg != GNUTLS_PK_EDDSA_ED448) #else if (pk_alg != GNUTLS_PK_EDDSA_ED25519) #endif { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Invalid x5c type, expected OKP"); ret = R_KEY_TYPE_NONE; } #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Error unsupported algorithm %s", gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)pk_alg)); ret = R_KEY_TYPE_NONE; } ret |= R_KEY_TYPE_PUBLIC; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Error gnutls import"); ret = R_KEY_TYPE_NONE; } gnutls_x509_crt_deinit(crt); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Error gnutls_x509_crt_init"); ret = R_KEY_TYPE_NONE; } o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5c - Error o_base64_decode (1)"); ret = R_KEY_TYPE_NONE; } } if (json_object_get(jwk, "x5u") != NULL) { if (!(x5u_flags & R_FLAG_IGNORE_REMOTE)) { // Get first x5u if (_r_get_http_content(json_string_value(json_object_get(jwk, "x5u")), x5u_flags, NULL, &x5u_datum) == RHN_OK) { data.data = (unsigned char *)x5u_datum.data; data.size = (unsigned int)x5u_datum.size; if (!gnutls_x509_crt_init(&crt)) { if (!gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)) { pk_alg = gnutls_x509_crt_get_pk_algorithm(crt, bits); bits_set = 1; if ((ret&R_KEY_TYPE_RSA)) { if (pk_alg != GNUTLS_PK_RSA) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5u - Invalid x5u type, expected RSA"); ret = R_KEY_TYPE_NONE; } #if GNUTLS_VERSION_NUMBER >= 0x030600 } else if ((ret&R_KEY_TYPE_EC)) { if (pk_alg != GNUTLS_PK_ECDSA) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5u - Invalid x5u type, expected EC"); ret = R_KEY_TYPE_NONE; } } else if ((ret&R_KEY_TYPE_EDDSA)) { #if GNUTLS_VERSION_NUMBER >= 0x03060e if (pk_alg != GNUTLS_PK_EDDSA_ED25519 && pk_alg != GNUTLS_PK_EDDSA_ED448) #else if (pk_alg != GNUTLS_PK_EDDSA_ED25519) #endif { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5u - Invalid x5u type, expected OKP"); ret = R_KEY_TYPE_NONE; } #endif } else { ret = R_KEY_TYPE_NONE; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5u - Error unsupported algorithm %s", gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)pk_alg)); } ret |= R_KEY_TYPE_PUBLIC; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type x5u - Error gnutls_x509_crt_import"); ret = R_KEY_TYPE_NONE; } gnutls_x509_crt_deinit(crt); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type - Error gnutls_x509_crt_init"); } o_free(x5u_datum.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type - Error getting x5u content"); } } } } } if (bits != NULL && !bits_set) { if (ret & R_KEY_TYPE_RSA) { if (o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "n")), json_string_length(json_object_get(jwk, "n")), NULL, &k_len)) { *bits = (unsigned int)k_len*8; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type - Error invalid base64url n value"); ret = R_KEY_TYPE_NONE; } } else if (ret & R_KEY_TYPE_EC) { if (0 == o_strcmp("P-256", json_string_value(json_object_get(jwk, "crv")))) { *bits = 256; } else if (0 == o_strcmp("P-384", json_string_value(json_object_get(jwk, "crv")))) { *bits = 384; } else if (0 == o_strcmp("P-521", json_string_value(json_object_get(jwk, "crv")))) { *bits = 521; } else if (0 == o_strcmp("secp256k1", json_string_value(json_object_get(jwk, "crv")))) { *bits = 256; } } else if (ret & R_KEY_TYPE_EDDSA) { if (0 == o_strcmp("Ed25519", json_string_value(json_object_get(jwk, "crv")))) { *bits = 256; } else if (0 == o_strcmp("Ed448", json_string_value(json_object_get(jwk, "crv")))) { *bits = 448; } } else if (ret & R_KEY_TYPE_ECDH) { if (0 == o_strcmp("X25519", json_string_value(json_object_get(jwk, "crv")))) { *bits = 256; } else if (0 == o_strcmp("X448", json_string_value(json_object_get(jwk, "crv")))) { *bits = 448; } } else if (ret & R_KEY_TYPE_HMAC) { if (o_base64url_decode((const unsigned char *)json_string_value(json_object_get(jwk, "k")), json_string_length(json_object_get(jwk, "k")), NULL, &k_len)) { *bits = (unsigned int)k_len*8; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_key_type - Error invalid base64url k value"); ret = R_KEY_TYPE_NONE; } } } return ret; } int r_jwk_extract_pubkey(jwk_t * jwk_privkey, jwk_t * jwk_pubkey, int x5u_flags) { int ret, type; if ((type = r_jwk_key_type(jwk_privkey, NULL, x5u_flags)) & R_KEY_TYPE_PRIVATE && jwk_pubkey != NULL) { if (json_string_length(json_object_get(jwk_privkey, "kid"))) { json_object_set_new(jwk_pubkey, "kid", json_string(json_string_value(json_object_get(jwk_privkey, "kid")))); } if (json_string_length(json_object_get(jwk_privkey, "alg"))) { json_object_set_new(jwk_pubkey, "alg", json_string(json_string_value(json_object_get(jwk_privkey, "alg")))); } if (json_string_length(json_object_get(jwk_privkey, "use"))) { json_object_set_new(jwk_pubkey, "use", json_string(json_string_value(json_object_get(jwk_privkey, "use")))); } if (json_string_length(json_object_get(jwk_privkey, "kty"))) { json_object_set_new(jwk_pubkey, "kty", json_string(json_string_value(json_object_get(jwk_privkey, "kty")))); } if (json_string_length(json_object_get(jwk_privkey, "crv"))) { json_object_set_new(jwk_pubkey, "crv", json_string(json_string_value(json_object_get(jwk_privkey, "crv")))); } if (json_object_get(jwk_privkey, "x5c") != NULL) { json_object_set_new(jwk_pubkey, "x5c", json_deep_copy(json_object_get(jwk_privkey, "x5c"))); } if (json_string_length(json_object_get(jwk_privkey, "x5u"))) { json_object_set_new(jwk_pubkey, "x5u", json_string(json_string_value(json_object_get(jwk_privkey, "x5u")))); } if (json_string_length(json_object_get(jwk_privkey, "x5t"))) { json_object_set_new(jwk_pubkey, "x5t", json_string(json_string_value(json_object_get(jwk_privkey, "x5t")))); } if (json_string_length(json_object_get(jwk_privkey, "x5t#S256"))) { json_object_set_new(jwk_pubkey, "x5t#S256", json_string(json_string_value(json_object_get(jwk_privkey, "x5t#S256")))); } ret = RHN_OK; if (type & R_KEY_TYPE_RSA) { json_object_set_new(jwk_pubkey, "e", json_string(json_string_value(json_object_get(jwk_privkey, "e")))); json_object_set_new(jwk_pubkey, "n", json_string(json_string_value(json_object_get(jwk_privkey, "n")))); } else if (type & R_KEY_TYPE_EC) { json_object_set_new(jwk_pubkey, "x", json_string(json_string_value(json_object_get(jwk_privkey, "x")))); json_object_set_new(jwk_pubkey, "y", json_string(json_string_value(json_object_get(jwk_privkey, "y")))); } else if (type & R_KEY_TYPE_EDDSA || type & R_KEY_TYPE_ECDH) { json_object_set_new(jwk_pubkey, "x", json_string(json_string_value(json_object_get(jwk_privkey, "x")))); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_extract_pubkey - Error invalid key type"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_extract_pubkey - Error invalid parameter"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_json_str(jwk_t * jwk, const char * input) { int ret; json_t * jwk_input; if (input != NULL && jwk != NULL) { if ((jwk_input = json_loads(input, JSON_DECODE_ANY, NULL)) != NULL) { ret = r_jwk_import_from_json_t(jwk, jwk_input); } else { ret = RHN_ERROR_PARAM; } json_decref(jwk_input); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_json_t(jwk_t * jwk, json_t * j_input) { int ret; if (j_input != NULL && json_is_object(j_input)) { if (!json_object_update(jwk, j_input)) { ret = r_jwk_is_valid(jwk); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_json_t - Error json_object_update"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_pem_der(jwk_t * jwk, int type, int format, const unsigned char * input, size_t input_len) { gnutls_x509_privkey_t x509_key = NULL; gnutls_privkey_t key = NULL; gnutls_pubkey_t pub = NULL; gnutls_x509_crt_t crt = NULL; gnutls_datum_t data; int ret, res; const unsigned char * input_end; unsigned char * input_copy, * input_copy_orig; size_t input_end_len; if (jwk != NULL && input != NULL && input_len) { if (R_X509_TYPE_UNSPECIFIED == type) { if (0 == o_strncmp((const char *)input, RHN_PEM_HEADER_CERT, o_strlen(RHN_PEM_HEADER_CERT))) { type = R_X509_TYPE_CERTIFICATE; } else if (0 == o_strncmp((const char *)input, RHN_PEM_HEADER_PUBKEY, o_strlen(RHN_PEM_HEADER_PUBKEY))) { type = R_X509_TYPE_PUBKEY; } else if (0 == o_strncmp((const char *)input, RHN_PEM_HEADER_PRIVKEY, o_strlen(RHN_PEM_HEADER_PRIVKEY)) || 0 == o_strncmp((const char *)input, RHN_PEM_HEADER_EC_PRIVKEY, o_strlen(RHN_PEM_HEADER_EC_PRIVKEY)) || 0 == o_strncmp((const char *)input, RHN_PEM_HEADER_RSA_PRIVKEY, o_strlen(RHN_PEM_HEADER_RSA_PRIVKEY)) || 0 == o_strncmp((const char *)input, RHN_PEM_HEADER_UNKNOWN_PRIVKEY, o_strlen(RHN_PEM_HEADER_UNKNOWN_PRIVKEY))) { type = R_X509_TYPE_PRIVKEY; } } input_copy = (unsigned char *)o_strndup((const char *)input, input_len); input_copy_orig = input_copy; switch (type) { case R_X509_TYPE_PUBKEY: if (!(res = gnutls_pubkey_init(&pub))) { data.data = (unsigned char *)input_copy; data.size = (unsigned int)input_len; if (!(res = gnutls_pubkey_import(pub, &data, format==R_FORMAT_PEM?GNUTLS_X509_FMT_PEM:GNUTLS_X509_FMT_DER))) { ret = r_jwk_import_from_gnutls_pubkey(jwk, pub); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error r_jwk_import_from_gnutls_pubkey: %s", gnutls_strerror(res)); ret = RHN_ERROR; } gnutls_pubkey_deinit(pub); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_pubkey_init: %s", gnutls_strerror(res)); ret = RHN_ERROR; } break; case R_X509_TYPE_PRIVKEY: if ((res = gnutls_privkey_init(&key)) < 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_privkey_init: %s", gnutls_strerror(res)); ret = RHN_ERROR; } else if ((res = gnutls_x509_privkey_init(&x509_key)) < 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_x509_privkey_init: %s", gnutls_strerror(res)); ret = RHN_ERROR; } else { data.data = (unsigned char *)input_copy; data.size = (unsigned int)input_len; if ((res = gnutls_x509_privkey_import(x509_key, &data, format==R_FORMAT_PEM?GNUTLS_X509_FMT_PEM:GNUTLS_X509_FMT_DER)) < 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_x509_privkey_import: %s", gnutls_strerror(res)); ret = RHN_ERROR_PARAM; } else if ((res = gnutls_privkey_import_x509(key, x509_key, 0)) < 0) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_privkey_import_x509: %s", gnutls_strerror(res)); ret = RHN_ERROR; } else { ret = r_jwk_import_from_gnutls_privkey(jwk, key); } } gnutls_privkey_deinit(key); gnutls_x509_privkey_deinit(x509_key); break; case R_X509_TYPE_CERTIFICATE: if (!(res = gnutls_x509_crt_init(&crt))) { if (format == R_FORMAT_PEM && o_strlen((const char *)input_copy) >= o_strlen(RHN_PEM_HEADER_CERT)) { input_end = (const unsigned char *)o_strstr((const char *)input_copy + o_strlen(RHN_PEM_HEADER_CERT), RHN_PEM_HEADER_CERT); if (input_end != NULL) { input_end_len = (size_t)(input_end - input_copy); } else { input_end_len = input_len; } data.data = (unsigned char *)input_copy; data.size = (unsigned int)input_end_len; if (!(res = gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM))) { if ((ret = r_jwk_import_from_gnutls_x509_crt(jwk, crt)) == RHN_OK) { ret = r_jwk_append_x5c(jwk, R_FORMAT_PEM, input_copy, input_end_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error r_jwk_import_from_gnutls_x509_crt (pem)"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_x509_crt_import (pem): %s", gnutls_strerror(res)); ret = RHN_ERROR_PARAM; } while (ret == RHN_OK && input_end != NULL) { input_copy += input_end_len; input_end = (const unsigned char *)o_strstr((const char *)input_copy + o_strlen(RHN_PEM_HEADER_CERT), RHN_PEM_HEADER_CERT); if (input_end != NULL) { input_end_len = (size_t)(input_end - input_copy); } else { input_end_len = o_strlen((const char *)input_copy); } ret = r_jwk_append_x5c(jwk, R_FORMAT_PEM, input_copy, input_end_len); } } else { data.data = (unsigned char *)input_copy; data.size = (unsigned int)input_len; if (!(res = gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER))) { if ((ret = r_jwk_import_from_gnutls_x509_crt(jwk, crt)) == RHN_OK) { ret = r_jwk_append_x5c(jwk, format, input_copy, input_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error r_jwk_import_from_gnutls_x509_crt (der)"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_x509_crt_import (der): %s", gnutls_strerror(res)); ret = RHN_ERROR_PARAM; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error gnutls_x509_crt_init: %s", gnutls_strerror(res)); ret = RHN_ERROR; } gnutls_x509_crt_deinit(crt); break; default: y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_pem_der - Error invalid type"); ret = RHN_ERROR_PARAM; break; } o_free(input_copy_orig); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_gnutls_privkey(jwk_t * jwk, gnutls_privkey_t key) { int ret, res, pk_type; unsigned int bits = 0; gnutls_x509_privkey_t x509_key = NULL; gnutls_datum_t m, e, d, p, q, u, e1, e2; unsigned char kid[64], kid_b64[128]; size_t kid_len = 64, kid_b64_len = 128; struct _o_datum dat = {0, NULL}; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_datum_t x, y, k; gnutls_ecc_curve_t curve; #endif if (jwk != NULL && key != NULL) { switch ((pk_type = gnutls_privkey_get_pk_algorithm(key, &bits))) { case GNUTLS_PK_RSA: if ((res = gnutls_privkey_export_rsa_raw2(key, &m, &e, &d, &p, &q, &u, &e1, &e2, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("RSA")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(m.data, m.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (2)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "n", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(e.data, e.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (4)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "e", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(d.data, d.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (6)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "d", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(p.data, p.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (8)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "p", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(q.data, q.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (10)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "q", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(u.data, u.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (12)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "qi", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(e1.data, e1.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (14)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "dp", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(e2.data, e2.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode_alloc (16)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "dq", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (gnutls_privkey_export_x509(key, &x509_key)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error gnutls_privkey_export_x509"); ret = RHN_ERROR; break; } if (gnutls_x509_privkey_get_key_id(x509_key, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error gnutls_x509_crt_get_key_id"); ret = RHN_ERROR; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey rsa - Error o_base64url_encode (5)"); ret = RHN_ERROR; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(m.data); gnutls_free(e.data); gnutls_free(d.data); gnutls_free(p.data); gnutls_free(q.data); gnutls_free(u.data); gnutls_free(e1.data); gnutls_free(e2.data); gnutls_x509_privkey_deinit(x509_key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey - Error gnutls_privkey_export_rsa_raw2"); ret = RHN_ERROR_PARAM; } break; #if GNUTLS_VERSION_NUMBER >= 0x030600 case GNUTLS_PK_ECDSA: if ((res = gnutls_privkey_export_ecc_raw2(key, &curve, &x, &y, &k, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("EC")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error o_base64url_encode_alloc (1)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(y.data, y.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error o_base64url_encode_alloc (2)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "y", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(k.data, k.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error o_base64url_encode_alloc (3)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "d", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; switch (curve) { case GNUTLS_ECC_CURVE_SECP521R1: json_object_set_new(jwk, "crv", json_string("P-521")); break; case GNUTLS_ECC_CURVE_SECP384R1: json_object_set_new(jwk, "crv", json_string("P-384")); break; case GNUTLS_ECC_CURVE_SECP256R1: json_object_set_new(jwk, "crv", json_string("P-256")); break; default: y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error curve"); ret = RHN_ERROR_PARAM; break; } if (gnutls_privkey_export_x509(key, &x509_key)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error gnutls_privkey_export_x509"); ret = RHN_ERROR; break; } if (gnutls_x509_privkey_get_key_id(x509_key, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error gnutls_x509_crt_get_key_id"); ret = RHN_ERROR; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error o_base64url_encode"); ret = RHN_ERROR; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); gnutls_free(y.data); gnutls_free(k.data); gnutls_x509_privkey_deinit(x509_key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey ecdsa - Error gnutls_privkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; case GNUTLS_PK_EDDSA_ED25519: #if GNUTLS_VERSION_NUMBER >= 0x03060e case GNUTLS_PK_EDDSA_ED448: #endif if ((res = gnutls_privkey_export_ecc_raw2(key, &curve, &x, NULL, &k, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("OKP")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode_alloc (1)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(k.data, k.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode_alloc (2)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "d", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (pk_type == GNUTLS_PK_EDDSA_ED25519) { json_object_set_new(jwk, "crv", json_string("Ed25519")); } else { json_object_set_new(jwk, "crv", json_string("Ed448")); } if (gnutls_privkey_export_x509(key, &x509_key)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_privkey_export_x509"); ret = RHN_ERROR; break; } if (gnutls_x509_privkey_get_key_id(x509_key, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_x509_crt_get_key_id"); ret = RHN_ERROR; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode"); ret = RHN_ERROR; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); gnutls_free(k.data); gnutls_x509_privkey_deinit(x509_key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_privkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; case GNUTLS_PK_ECDH_X25519: #if GNUTLS_VERSION_NUMBER >= 0x03060e case GNUTLS_PK_ECDH_X448: #endif if ((res = gnutls_privkey_export_ecc_raw2(key, &curve, &x, NULL, &k, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("OKP")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode_alloc (1)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(k.data, k.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode_alloc (2)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "d", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (pk_type == GNUTLS_PK_EDDSA_ED25519) { json_object_set_new(jwk, "crv", json_string("X25519")); } else { json_object_set_new(jwk, "crv", json_string("X448")); } if (gnutls_privkey_export_x509(key, &x509_key)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_privkey_export_x509"); ret = RHN_ERROR; break; } if (gnutls_x509_privkey_get_key_id(x509_key, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_x509_crt_get_key_id"); ret = RHN_ERROR; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error o_base64url_encode"); ret = RHN_ERROR; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); gnutls_free(k.data); gnutls_x509_privkey_deinit(x509_key); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_privkey eddsa - Error gnutls_privkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; #endif default: ret = RHN_ERROR_PARAM; break; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_gnutls_pubkey(jwk_t * jwk, gnutls_pubkey_t pub) { int ret, res, pk_type; unsigned int bits = 0; gnutls_datum_t m, e; unsigned char kid[64], kid_b64[128]; size_t kid_len = 64, kid_b64_len = 128; struct _o_datum dat = {0, NULL}; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_datum_t x, y; gnutls_ecc_curve_t curve; #endif if (jwk != NULL && pub != NULL) { switch ((pk_type = gnutls_pubkey_get_pk_algorithm(pub, &bits))) { case GNUTLS_PK_RSA: if ((res = gnutls_pubkey_export_rsa_raw2(pub, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("RSA")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(m.data, m.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey rsa - Error o_base64url_encode_alloc (1)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "n", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(e.data, e.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey rsa - Error o_base64url_encode_alloc (42)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "e", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (gnutls_pubkey_get_key_id(pub, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey rsa - Error gnutls_pubkey_get_key_id"); ret = RHN_ERROR; break; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey rsa - Error o_base64url_encode"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(m.data); gnutls_free(e.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey - Error gnutls_pubkey_export_rsa_raw2"); ret = RHN_ERROR_PARAM; } break; #if GNUTLS_VERSION_NUMBER >= 0x030600 case GNUTLS_PK_ECDSA: if ((res = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, &y, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("EC")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error o_base64url_encode_alloc (1)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (!o_base64url_encode_alloc(y.data, y.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error o_base64url_encode_alloc (2)"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "y", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; switch (curve) { case GNUTLS_ECC_CURVE_SECP521R1: json_object_set_new(jwk, "crv", json_string("P-521")); break; case GNUTLS_ECC_CURVE_SECP384R1: json_object_set_new(jwk, "crv", json_string("P-384")); break; case GNUTLS_ECC_CURVE_SECP256R1: json_object_set_new(jwk, "crv", json_string("P-256")); break; default: y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error curve"); ret = RHN_ERROR_PARAM; break; } if (ret != RHN_OK) { break; } if (gnutls_pubkey_get_key_id(pub, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error gnutls_pubkey_get_key_id"); ret = RHN_ERROR; break; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error o_base64url_encode"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); gnutls_free(y.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdsa - Error gnutls_pubkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; case GNUTLS_PK_EDDSA_ED25519: #if GNUTLS_VERSION_NUMBER >= 0x03060e case GNUTLS_PK_EDDSA_ED448: #endif if ((res = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, NULL, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("OKP")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey eddsa - Error o_base64url_encode_alloc"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (pk_type == GNUTLS_PK_EDDSA_ED25519) { json_object_set_new(jwk, "crv", json_string("Ed25519")); } else { json_object_set_new(jwk, "crv", json_string("Ed448")); } if (ret != RHN_OK) { break; } if (gnutls_pubkey_get_key_id(pub, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey eddsa - Error gnutls_pubkey_get_key_id"); ret = RHN_ERROR; break; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey eddsa - Error o_base64url_encode"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey eddsa - Error gnutls_pubkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; case GNUTLS_PK_ECDH_X25519: #if GNUTLS_VERSION_NUMBER >= 0x03060e case GNUTLS_PK_ECDH_X448: #endif if ((res = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, NULL, GNUTLS_EXPORT_FLAG_NO_LZ)) == GNUTLS_E_SUCCESS) { json_object_set_new(jwk, "kty", json_string("OKP")); ret = RHN_OK; do { if (!o_base64url_encode_alloc(x.data, x.size, &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdh - Error o_base64url_encode_alloc"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "x", json_stringn((const char *)dat.data, dat.size)); o_free(dat.data); dat.data = NULL; if (pk_type == GNUTLS_PK_EDDSA_ED25519) { json_object_set_new(jwk, "crv", json_string("X25519")); } else { json_object_set_new(jwk, "crv", json_string("X448")); } if (ret != RHN_OK) { break; } if (gnutls_pubkey_get_key_id(pub, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdh - Error gnutls_pubkey_get_key_id"); ret = RHN_ERROR; break; } if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdh - Error o_base64url_encode"); ret = RHN_ERROR; break; } json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } while (0); gnutls_free(x.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_pubkey ecdh - Error gnutls_pubkey_export_ecc_raw2"); ret = RHN_ERROR_PARAM; } break; #endif default: ret = RHN_ERROR_PARAM; break; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_gnutls_x509_crt(jwk_t * jwk, gnutls_x509_crt_t crt) { int ret, res; gnutls_pubkey_t pub; unsigned char kid[64], kid_b64[128]; size_t kid_len = 64, kid_b64_len = 128; if (jwk != NULL && crt != NULL) { if (!(res = gnutls_pubkey_init(&pub))) { if (!(res = gnutls_pubkey_import_x509(pub, crt, 0))) { ret = r_jwk_import_from_gnutls_pubkey(jwk, pub); if (ret == RHN_OK) { if (gnutls_x509_crt_get_key_id(crt, GNUTLS_KEYID_USE_SHA256, kid, &kid_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_x509_crt x509 - Error gnutls_x509_crt_get_key_id"); ret = RHN_ERROR; } else if (!o_base64url_encode(kid, kid_len, kid_b64, &kid_b64_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_x509_crt x509 - Error o_base64url_encode"); ret = RHN_ERROR; } else { json_object_set_new(jwk, "kid", json_stringn((const char *)kid_b64, kid_b64_len)); } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_x509_crt x509 - Error gnutls_pubkey_import_x509"); ret = RHN_ERROR_PARAM; } gnutls_pubkey_deinit(pub); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_gnutls_x509_crt x509 - Error gnutls_pubkey_init"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_x5u(jwk_t * jwk, int x5u_flags, const char * x5u) { int ret; struct _o_datum x5u_datum = {0, NULL}; if (jwk != NULL && x5u != NULL) { if (_r_get_http_content(x5u, x5u_flags, NULL, &x5u_datum) == RHN_OK) { if (r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (unsigned const char *)x5u_datum.data, x5u_datum.size) == RHN_OK) { ret = RHN_OK; } else { ret = RHN_ERROR; } o_free(x5u_datum.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_x5u - Error getting x5u content"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_x5c(jwk_t * jwk, const char * x5c) { int ret; struct _o_datum dat = {0, NULL}; if (jwk != NULL && x5c != NULL) { if (o_base64_decode_alloc((const unsigned char *)x5c, o_strlen(x5c), &dat)) { if (r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_DER, dat.data, dat.size) == RHN_OK) { ret = RHN_OK; } else { ret = RHN_ERROR; } o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_x5u - Error o_base64_decode x5c"); ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_symmetric_key(jwk_t * jwk, const unsigned char * key, size_t key_len) { int ret; char * key_b64 = NULL; struct _o_datum dat = {0, NULL}; if (jwk != NULL && key != NULL && key_len) { if (o_base64url_encode_alloc(key, key_len, &dat)) { key_b64 = o_strndup((const char *)dat.data, dat.size); if (r_jwk_set_property_str(jwk, "kty", "oct") == RHN_OK && r_jwk_set_property_str(jwk, "k", (const char *)key_b64) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_import_from_symmetric_key - Error setting key data in jwk"); ret = RHN_ERROR; } o_free(dat.data); } else { ret = RHN_ERROR_PARAM; } o_free(key_b64); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwk_import_from_password(jwk_t * jwk, const char * password) { return r_jwk_import_from_symmetric_key(jwk, (const unsigned char *)password, o_strlen(password)); } jwk_t * r_jwk_quick_import(rhn_import type, ...) { va_list vl; jwk_t * jwk = NULL; int ret, i_val; const char * str; json_t * j_jwk; const unsigned char * data; size_t data_len; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; gnutls_x509_crt_t crt; if (r_jwk_init(&jwk) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_quick_import - Error r_jwk_init"); return NULL; } else { va_start(vl, type); switch (type) { case R_IMPORT_JSON_STR: str = va_arg(vl, const char *); ret = r_jwk_import_from_json_str(jwk, str); break; case R_IMPORT_JSON_T: j_jwk = va_arg(vl, json_t *); ret = r_jwk_import_from_json_t(jwk, j_jwk); break; case R_IMPORT_PEM: i_val = va_arg(vl, int); data = va_arg(vl, const unsigned char *); data_len = va_arg(vl, size_t); ret = r_jwk_import_from_pem_der(jwk, i_val, R_FORMAT_PEM, data, data_len); break; case R_IMPORT_DER: i_val = va_arg(vl, int); data = va_arg(vl, const unsigned char *); data_len = va_arg(vl, size_t); ret = r_jwk_import_from_pem_der(jwk, i_val, R_FORMAT_DER, data, data_len); break; case R_IMPORT_G_PRIVKEY: privkey = va_arg(vl, gnutls_privkey_t); ret = r_jwk_import_from_gnutls_privkey(jwk, privkey); break; case R_IMPORT_G_PUBKEY: pubkey = va_arg(vl, gnutls_pubkey_t); ret = r_jwk_import_from_gnutls_pubkey(jwk, pubkey); break; case R_IMPORT_G_CERT: crt = va_arg(vl, gnutls_x509_crt_t); ret = r_jwk_import_from_gnutls_x509_crt(jwk, crt); break; case R_IMPORT_X5U: i_val = va_arg(vl, int); str = va_arg(vl, const char *); ret = r_jwk_import_from_x5u(jwk, i_val, str); break; case R_IMPORT_SYMKEY: data = va_arg(vl, const unsigned char *); data_len = va_arg(vl, size_t); ret = r_jwk_import_from_symmetric_key(jwk, data, data_len); break; case R_IMPORT_PASSWORD: str = va_arg(vl, const char *); ret = r_jwk_import_from_password(jwk, str); break; default: y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_quick_import - Invalid type"); ret = RHN_ERROR_PARAM; break; } va_end(vl); if (ret != RHN_OK) { r_jwk_free(jwk); jwk = NULL; } return jwk; } } jwk_t * r_jwk_copy(jwk_t * jwk) { if (jwk != NULL) { return json_deep_copy(jwk); } else { return NULL; } } int r_jwk_equal(jwk_t * jwk1, jwk_t * jwk2) { return json_equal(jwk1, jwk2); } char * r_jwk_export_to_json_str(jwk_t * jwk, int pretty) { char * str_jwk_export = NULL; if (jwk != NULL) { str_jwk_export = json_dumps(jwk, pretty?JSON_INDENT(2):JSON_COMPACT); } return str_jwk_export; } json_t * r_jwk_export_to_json_t(jwk_t * jwk) { if (json_object_size(jwk)) { return json_deep_copy(jwk); } else { return NULL; } } gnutls_privkey_t r_jwk_export_to_gnutls_privkey(jwk_t * jwk) { gnutls_privkey_t privkey = NULL; gnutls_x509_privkey_t x509_key = NULL; gnutls_ecc_curve_t curve; gnutls_datum_t m = {NULL, 0}, e = {NULL, 0}, d = {NULL, 0}, p = {NULL, 0}, q = {NULL, 0}, u = {NULL, 0}, e1 = {NULL, 0}, e2 = {NULL, 0}, x = {NULL, 0}, y = {NULL, 0}, k = {NULL, 0}, data = {NULL, 0}; struct _o_datum dat = {0, NULL}; int res, type = r_jwk_key_type(jwk, NULL, R_FLAG_IGNORE_REMOTE); if (type & R_KEY_TYPE_PRIVATE) { if (json_object_get(jwk, "n") == NULL && json_object_get(jwk, "x") == NULL && json_array_get(json_object_get(jwk, "x5c"), 0) != NULL) { // Export first x5c if (o_base64_decode_alloc((const unsigned char *)json_string_value(json_array_get(json_object_get(jwk, "x5c"), 0)), json_string_length(json_array_get(json_object_get(jwk, "x5c"), 0)), &dat)) { if (!gnutls_x509_privkey_init(&x509_key)) { if (!gnutls_privkey_init(&privkey)) { data.data = dat.data; data.size = (unsigned int)dat.size; if (!gnutls_x509_privkey_import(x509_key, &data, GNUTLS_X509_FMT_DER)) { if ((res = gnutls_privkey_import_x509(privkey, x509_key, 0)) < 0) { res = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_import_x509 rsa"); res = RHN_ERROR; gnutls_privkey_deinit(privkey); privkey = NULL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_x509_privkey_import rsa"); res = RHN_ERROR; gnutls_privkey_deinit(privkey); privkey = NULL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey x5c - Error gnutls_privkey_init"); res = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_init rsa"); res = RHN_ERROR; } gnutls_x509_privkey_deinit(x509_key); o_free(dat.data); dat.data = NULL; dat.size = 0; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey x5c - Error o_base64_decode_alloc (1)"); res = RHN_ERROR_MEMORY; } } else if (type & R_KEY_TYPE_RSA) { res = RHN_OK; do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "n")), json_string_length(json_object_get(jwk, "n")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (n)"); res = RHN_ERROR; break; } m.data = dat.data; m.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "e")), json_string_length(json_object_get(jwk, "e")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (e)"); res = RHN_ERROR; break; } e.data = dat.data; e.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (d)"); res = RHN_ERROR; break; } d.data = dat.data; d.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "p")), json_string_length(json_object_get(jwk, "p")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (p)"); res = RHN_ERROR; break; } p.data = dat.data; p.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "q")), json_string_length(json_object_get(jwk, "q")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (q)"); res = RHN_ERROR; break; } q.data = dat.data; q.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "qi")), json_string_length(json_object_get(jwk, "qi")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (qi)"); res = RHN_ERROR; break; } u.data = dat.data; u.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "dp")), json_string_length(json_object_get(jwk, "dp")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (dp)"); res = RHN_ERROR; break; } e1.data = dat.data; e1.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "dq")), json_string_length(json_object_get(jwk, "dq")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (dq)"); res = RHN_ERROR; break; } e2.data = dat.data; e2.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (gnutls_privkey_init(&privkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_init rsa"); res = RHN_ERROR; break; } if (gnutls_privkey_import_rsa_raw(privkey, &m, &e, &d, &p, &q, &u, &e1, &e2)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_import_rsa_raw"); res = RHN_ERROR; break; } } while (0); if (res != RHN_OK) { if (privkey != NULL) { gnutls_privkey_deinit(privkey); privkey = NULL; } } o_free(m.data); o_free(e.data); o_free(d.data); o_free(p.data); o_free(q.data); o_free(u.data); o_free(e1.data); o_free(e2.data); } else if (type & R_KEY_TYPE_EC) { res = RHN_OK; do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (x)"); res = RHN_ERROR; break; } x.data = dat.data; x.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "y")), json_string_length(json_object_get(jwk, "y")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (y)"); res = RHN_ERROR; break; } y.data = dat.data; y.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (d)"); res = RHN_ERROR; break; } k.data = dat.data; k.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (0 == o_strcmp("P-521", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP521R1; } else if (0 == o_strcmp("P-384", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP384R1; } else if (0 == o_strcmp("P-256", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP256R1; //} else if (0 == o_strcmp("secp256k1", json_string_value(json_object_get(jwk, "crv")))) { // curve = GNUTLS_ECC_CURVE_SECP256K1; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error crv data"); res = RHN_ERROR; break; } if (gnutls_privkey_init(&privkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_init ec"); res = RHN_ERROR; break; } if (gnutls_privkey_import_ecc_raw(privkey, curve, &x, &y, &k)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_import_ecc_raw"); res = RHN_ERROR; break; } } while (0); if (res != RHN_OK) { if (privkey != NULL) { gnutls_privkey_deinit(privkey); privkey = NULL; } } o_free(x.data); o_free(y.data); o_free(k.data); #if GNUTLS_VERSION_NUMBER >= 0x030600 } else if (type & R_KEY_TYPE_EDDSA || type & R_KEY_TYPE_ECDH) { res = RHN_OK; do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (x)"); res = RHN_ERROR; break; } x.data = dat.data; x.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "d")), json_string_length(json_object_get(jwk, "d")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error o_base64url_decode_alloc (d)"); res = RHN_ERROR; break; } k.data = dat.data; k.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (0 == o_strcmp("Ed25519", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_ED25519; #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (0 == o_strcmp("Ed448", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_ED448; #endif #if 0 // disabled } else if (0 == o_strcmp("X25519", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_X25519; #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (0 == o_strcmp("X448", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_X448; #endif #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error crv data"); res = RHN_ERROR; break; } if (gnutls_privkey_init(&privkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_init ec"); res = RHN_ERROR; break; } if (gnutls_privkey_import_ecc_raw(privkey, curve, &x, NULL, &k)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error gnutls_privkey_import_ecc_raw"); res = RHN_ERROR; break; } } while (0); if (res != RHN_OK) { if (privkey != NULL) { gnutls_privkey_deinit(privkey); privkey = NULL; } } o_free(x.data); o_free(k.data); } else if (type & R_KEY_TYPE_EDDSA || type & R_KEY_TYPE_ECDH) { #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - invalid key format, expected 'RSA' or 'EC'"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - invalid key type, expected private key"); } return privkey; } gnutls_pubkey_t r_jwk_export_to_gnutls_pubkey(jwk_t * jwk, int x5u_flags) { gnutls_pubkey_t pubkey = NULL; gnutls_privkey_t privkey = NULL; gnutls_x509_crt_t crt; gnutls_datum_t m = {NULL, 0}, e = {NULL, 0}, data = {NULL, 0}; int res, type = r_jwk_key_type(jwk, NULL, x5u_flags); struct _o_datum dat = {0, NULL}, x5u_datum = {0, NULL}; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_ecc_curve_t curve; gnutls_datum_t x = {NULL, 0}, y = {NULL, 0}; #endif if (type & (R_KEY_TYPE_PUBLIC|R_KEY_TYPE_PRIVATE)) { if (json_object_get(jwk, "n") == NULL && json_object_get(jwk, "x") == NULL && (json_array_get(json_object_get(jwk, "x5c"), 0) != NULL || json_object_get(jwk, "x5u") != NULL)) { if (json_array_get(json_object_get(jwk, "x5c"), 0) != NULL) { // Export first x5c if (o_base64_decode_alloc((const unsigned char *)json_string_value(json_array_get(json_object_get(jwk, "x5c"), 0)), json_string_length(json_array_get(json_object_get(jwk, "x5c"), 0)), &dat)) { if (!gnutls_x509_crt_init(&crt)) { if (!gnutls_pubkey_init(&pubkey)) { data.data = dat.data; data.size = (unsigned int)dat.size; if (!gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER)) { if (!gnutls_pubkey_import_x509(pubkey, crt, 0)) { res = RHN_OK; } else { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5c - Error gnutls_pubkey_import_x509"); res = RHN_ERROR; } } else { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5c - Error gnutls_pubkey_import"); res = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5c - Error gnutls_pubkey_init rsa"); res = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5c - Error gnutls_x509_crt_init"); res = RHN_ERROR; } gnutls_x509_crt_deinit(crt); o_free(dat.data); dat.data = NULL; dat.size = 0; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5c - Error o_base64_decode (2)"); res = RHN_ERROR_MEMORY; } o_free(data.data); } else { if (!(x5u_flags & R_FLAG_IGNORE_REMOTE)) { // Get x5u if (_r_get_http_content(json_string_value(json_object_get(jwk, "x5u")), x5u_flags, NULL, &x5u_datum) == RHN_OK) { if (!gnutls_pubkey_init(&pubkey)) { if (!gnutls_x509_crt_init(&crt)) { data.data = (unsigned char *)x5u_datum.data; data.size = (unsigned int)x5u_datum.size; if (!gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)) { if (!gnutls_pubkey_import_x509(pubkey, crt, 0)) { res = RHN_OK; } else { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5u - Error gnutls_pubkey_import_x509"); res = RHN_ERROR; } } else { gnutls_pubkey_deinit(pubkey); pubkey = NULL; y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5u - Error gnutls_pubkey_import"); res = RHN_ERROR; } gnutls_x509_crt_deinit(crt); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5u - Error gnutls_x509_crt_init"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5u - Error gnutls_pubkey_init"); } o_free(x5u_datum.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey x5u - Error getting x5u content"); } } else { res = RHN_ERROR_UNSUPPORTED; } } } else if (type & R_KEY_TYPE_RSA) { res = RHN_OK; if (!(type & R_KEY_TYPE_PRIVATE)) { do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "n")), json_string_length(json_object_get(jwk, "n")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error o_base64url_decode_alloc (n)"); res = RHN_ERROR; break; } m.data = dat.data; m.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "e")), json_string_length(json_object_get(jwk, "e")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error o_base64url_decode_alloc (e)"); res = RHN_ERROR; break; } e.data = dat.data; e.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (gnutls_pubkey_init(&pubkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_privkey_init rsa"); res = RHN_ERROR; break; } if (gnutls_pubkey_import_rsa_raw(pubkey, &m, &e)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_import_rsa_raw"); res = RHN_ERROR; break; } } while (0); } else { do { if ((privkey = r_jwk_export_to_gnutls_privkey(jwk)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error r_jwk_export_to_gnutls_privkey rsa"); res = RHN_ERROR; break; } if (gnutls_pubkey_init(&pubkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_privkey_init rsa"); res = RHN_ERROR; break; } if (gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE|GNUTLS_KEY_DATA_ENCIPHERMENT, 0)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_import_privkey rsa"); res = RHN_ERROR; break; } } while (0); gnutls_privkey_deinit(privkey); } if (res != RHN_OK) { if (pubkey != NULL) { gnutls_pubkey_deinit(pubkey); pubkey = NULL; } } o_free(m.data); o_free(e.data); #if GNUTLS_VERSION_NUMBER >= 0x030600 } else if (type & R_KEY_TYPE_EC) { res = RHN_OK; do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error o_base64url_decode_alloc (x)"); res = RHN_ERROR; break; } x.data = dat.data; x.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "y")), json_string_length(json_object_get(jwk, "y")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error o_base64url_decode_alloc (y)"); res = RHN_ERROR; break; } y.data = dat.data; y.size = (unsigned int)dat.size; dat.data = NULL; dat.size = 0; if (0 == o_strcmp("P-521", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP521R1; } else if (0 == o_strcmp("P-384", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP384R1; } else if (0 == o_strcmp("P-256", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_SECP256R1; //} else if (0 == o_strcmp("secp256k1", json_string_value(json_object_get(jwk, "crv")))) { // curve = GNUTLS_ECC_CURVE_SECP256K1; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error crv data"); res = RHN_ERROR; break; } if (gnutls_pubkey_init(&pubkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_init ec"); res = RHN_ERROR; break; } if (gnutls_pubkey_import_ecc_raw(pubkey, curve, &x, &y)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_import_ecc_raw"); res = RHN_ERROR; break; } } while (0); if (res != RHN_OK) { if (pubkey != NULL) { gnutls_pubkey_deinit(pubkey); pubkey = NULL; } } o_free(x.data); o_free(y.data); } else if (type & R_KEY_TYPE_EDDSA || type & R_KEY_TYPE_ECDH) { res = RHN_OK; do { if (!o_base64url_decode_alloc((const unsigned char *)json_string_value(json_object_get(jwk, "x")), json_string_length(json_object_get(jwk, "x")), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error o_base64url_decode_alloc (x)"); res = RHN_ERROR; break; } x.data = dat.data; x.size = (unsigned int)dat.size; if (0 == o_strcmp("Ed25519", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_ED25519; #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (0 == o_strcmp("Ed448", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_ED448; #endif #if 0 // disabled } else if (0 == o_strcmp("X25519", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_X25519; #if GNUTLS_VERSION_NUMBER >= 0x03060e } else if (0 == o_strcmp("X448", json_string_value(json_object_get(jwk, "crv")))) { curve = GNUTLS_ECC_CURVE_X448; #endif #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_privkey - Error crv data"); res = RHN_ERROR; break; } if (gnutls_pubkey_init(&pubkey)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_init ec"); res = RHN_ERROR; break; } if (gnutls_pubkey_import_ecc_raw(pubkey, curve, &x, NULL)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error gnutls_pubkey_import_ecc_raw"); res = RHN_ERROR; break; } } while (0); if (res != RHN_OK) { if (pubkey != NULL) { gnutls_pubkey_deinit(pubkey); pubkey = NULL; } } o_free(x.data); #endif } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error invalid key type"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_pubkey - Error not public key"); } return pubkey; } gnutls_x509_crt_t r_jwk_export_to_gnutls_crt(jwk_t * jwk, int x5u_flags) { gnutls_x509_crt_t crt = NULL; gnutls_datum_t data = {NULL, 0}; int type = r_jwk_key_type(jwk, NULL, x5u_flags); struct _o_datum dat = {0, NULL}, x5u_datum = {0, NULL}; if (type & (R_KEY_TYPE_PUBLIC)) { if (json_array_get(json_object_get(jwk, "x5c"), 0) != NULL || json_object_get(jwk, "x5u") != NULL) { if (json_array_get(json_object_get(jwk, "x5c"), 0) != NULL) { // Export first x5c if (o_base64_decode_alloc((const unsigned char *)json_string_value(json_array_get(json_object_get(jwk, "x5c"), 0)), json_string_length(json_array_get(json_object_get(jwk, "x5c"), 0)), &dat)) { if (!gnutls_x509_crt_init(&crt)) { data.data = dat.data; data.size = (unsigned int)dat.size; if (gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5c - Error gnutls_pubkey_import"); } o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5c - Error gnutls_x509_crt_init"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5c - Error o_base64_decode_alloc"); } } else { if (!(x5u_flags & R_FLAG_IGNORE_REMOTE)) { // Get x5u if (_r_get_http_content(json_string_value(json_object_get(jwk, "x5u")), x5u_flags, NULL, &x5u_datum) == RHN_OK) { if (!gnutls_x509_crt_init(&crt)) { data.data = (unsigned char *)x5u_datum.data; data.size = (unsigned int)x5u_datum.size; if (gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5u - Error gnutls_pubkey_import"); gnutls_x509_crt_deinit(crt); crt = NULL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5u - Error gnutls_x509_crt_init"); } o_free(x5u_datum.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt x5u - Error getting x5u content"); } } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt - Error invalid key type"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_gnutls_crt - Error not public key"); } return crt; } int r_jwk_export_to_pem_der(jwk_t * jwk, int format, unsigned char * output, size_t * output_len, int x5u_flags) { gnutls_pubkey_t pubkey = NULL; gnutls_privkey_t privkey = NULL; gnutls_x509_privkey_t x509_privkey = NULL; int res, ret, type = r_jwk_key_type(jwk, NULL, x5u_flags); int test_size = (output==NULL); if (type & R_KEY_TYPE_PRIVATE) { if ((privkey = r_jwk_export_to_gnutls_privkey(jwk)) != NULL) { if (!gnutls_privkey_export_x509(privkey, &x509_privkey)) { if (!(res = gnutls_x509_privkey_export(x509_privkey, format==R_FORMAT_PEM?GNUTLS_X509_FMT_PEM:GNUTLS_X509_FMT_DER, output, output_len))) { ret = RHN_OK; } else if (res == GNUTLS_E_SHORT_MEMORY_BUFFER) { if (!test_size) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error buffer size"); } ret = RHN_ERROR_PARAM; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error gnutls_x509_privkey_export"); ret = RHN_ERROR; } gnutls_x509_privkey_deinit(x509_privkey); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error gnutls_privkey_export_x509"); ret = RHN_ERROR; } gnutls_privkey_deinit(privkey); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error r_jwk_export_to_gnutls_privkey"); ret = RHN_ERROR; } } else if (type & R_KEY_TYPE_PUBLIC) { if ((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags)) != NULL) { if (!(res = gnutls_pubkey_export(pubkey, format==R_FORMAT_PEM?GNUTLS_X509_FMT_PEM:GNUTLS_X509_FMT_DER, output, output_len))) { ret = RHN_OK; } else if (res == GNUTLS_E_SHORT_MEMORY_BUFFER) { if (!test_size) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error buffer size"); } ret = RHN_ERROR_PARAM; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error gnutls_pubkey_export"); ret = RHN_ERROR; } gnutls_pubkey_deinit(pubkey); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - Error r_jwk_export_to_gnutls_pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_pem_der - invalid key type, exptected 'RSA' or 'EC'"); ret = RHN_ERROR; } return ret; } int r_jwk_export_to_symmetric_key(jwk_t * jwk, unsigned char * key, size_t * key_len) { int ret; const char * k; size_t k_len = 0, k_expected = 0; if (jwk != NULL && key_len != NULL) { if (r_jwk_key_type(jwk, NULL, 0) & R_KEY_TYPE_SYMMETRIC) { k = r_jwk_get_property_str(jwk, "k"); if ((k_len = o_strlen(k))) { if (o_base64url_decode((const unsigned char *)k, k_len, NULL, &k_expected)) { if (k_expected <= *key_len) { if (o_base64url_decode((const unsigned char *)k, k_len, key, key_len)) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_symmetric_key - Error o_base64url_decode"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_symmetric_key - Error invalid key"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_export_to_symmetric_key - Error getting key"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } const char * r_jwk_get_property_str(jwk_t * jwk, const char * key) { if (jwk != NULL && !o_strnullempty(key)) { if (json_is_string(json_object_get(jwk, key))) { return json_string_value(json_object_get(jwk, key)); } else { return NULL; } } else { return NULL; } } const char * r_jwk_get_property_array(jwk_t * jwk, const char * key, size_t index) { if (jwk != NULL && !o_strnullempty(key)) { if (json_is_array(json_object_get(jwk, key))) { return json_string_value(json_array_get(json_object_get(jwk, key), index)); } else { return NULL; } } else { return NULL; } return NULL; } int r_jwk_get_property_array_size(jwk_t * jwk, const char * key) { if (jwk != NULL && !o_strnullempty(key)) { if (json_is_array(json_object_get(jwk, key))) { return (int)json_array_size(json_object_get(jwk, key)); } else { return -1; } } else { return -1; } return -1; } int r_jwk_set_property_str(jwk_t * jwk, const char * key, const char * value) { if (jwk != NULL && !o_strnullempty(key) && !o_strnullempty(value)) { if (!json_object_set_new(jwk, key, json_string(value))) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_set_property_str, error setting value"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwk_set_property_array(jwk_t * jwk, const char * key, size_t index, const char * value) { if (jwk != NULL && !o_strnullempty(key) && !o_strnullempty(value)) { if ((json_object_get(jwk, key) != NULL && !json_is_array(json_object_get(jwk, key))) || (json_is_array(json_object_get(jwk, key)) && json_array_size(json_object_get(jwk, key)) <= index)) { return RHN_ERROR_PARAM; } else if (json_object_get(jwk, key) == NULL && !index) { if (!json_object_set_new(jwk, key, json_array()) && !json_array_append_new(json_object_get(jwk, key), json_string(value))) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_set_property_array, error appending value"); return RHN_ERROR; } } else { if (!json_array_set_new(json_object_get(jwk, key), index, json_string(value))) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_set_property_array, error setting value"); return RHN_ERROR; } } } else { return RHN_ERROR_PARAM; } } int r_jwk_append_property_array(jwk_t * jwk, const char * key, const char * value) { if (jwk != NULL && !o_strnullempty(key) && !o_strnullempty(value)) { if (json_object_get(jwk, key) != NULL && !json_is_array(json_object_get(jwk, key))) { return RHN_ERROR_PARAM; } else if (json_object_get(jwk, key) == NULL) { json_object_set_new(jwk, key, json_array()); } if (!json_array_append_new(json_object_get(jwk, key), json_string(value))) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_append_property_array, error setting value"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwk_delete_property_str(jwk_t * jwk, const char * key) { if (jwk != NULL && !o_strnullempty(key)) { if (!json_object_del(jwk, key)) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_delete_property_str, error deleting value"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwk_delete_property_array_at(jwk_t * jwk, const char * key, size_t index) { if (jwk != NULL && !o_strnullempty(key) && json_is_array(json_object_get(jwk, key)) && json_array_size(json_object_get(jwk, key)) > index) { if (!json_array_remove(json_object_get(jwk, key), index)) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_delete_property_array_at, error deleting index"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwk_append_x5c(jwk_t * jwk, int format, const unsigned char * input, size_t input_len) { int ret, res; gnutls_x509_crt_t crt = NULL; gnutls_datum_t data, x5c = {NULL, 0}; char * x5c_b64 = NULL; struct _o_datum dat = {0, NULL}; if (jwk != NULL && input != NULL && input_len) { if (!(res = gnutls_x509_crt_init(&crt))) { data.data = (unsigned char *)input; data.size = (unsigned int)input_len; if (!(res = gnutls_x509_crt_import(crt, &data, format==R_FORMAT_PEM?GNUTLS_X509_FMT_PEM:GNUTLS_X509_FMT_DER))) { if (!(res = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &x5c))) { if (o_base64_encode_alloc(x5c.data, x5c.size, &dat)) { x5c_b64 = o_strndup((const char *)dat.data, dat.size); ret = r_jwk_append_property_array(jwk, "x5c", (const char *)x5c_b64); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_append_x5c - Error o_base64_encode_alloc for x5c_b64"); ret = RHN_ERROR; } o_free(x5c_b64); o_free(dat.data); gnutls_free(x5c.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_append_x5c - Error gnutls_x509_crt_export2: %s", gnutls_strerror(res)); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_append_x5c - Error gnutls_x509_crt_import: %s", gnutls_strerror(res)); ret = RHN_ERROR_PARAM; } gnutls_x509_crt_deinit(crt); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_append_x5c - Error gnutls_x509_crt_init: %s", gnutls_strerror(res)); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } char * r_jwk_thumbprint(jwk_t * jwk, int hash, int x5u_flags) { int type; json_t * key_members = json_object(), * key_export = r_jwk_export_to_json_t(jwk); char * thumb = NULL, * key_dump; unsigned char jwk_hash[128] = {0}, jwk_hash_b64[256] = {0}; gnutls_digest_algorithm_t alg = GNUTLS_DIG_NULL; size_t jwk_hash_b64_len = 256; switch (hash) { case R_JWK_THUMB_SHA256: alg = GNUTLS_DIG_SHA256; break; case R_JWK_THUMB_SHA384: alg = GNUTLS_DIG_SHA384; break; case R_JWK_THUMB_SHA512: alg = GNUTLS_DIG_SHA512; break; } if (alg != GNUTLS_DIG_NULL) { if (key_members != NULL) { type = r_jwk_key_type(jwk, NULL, x5u_flags); if (type & R_KEY_TYPE_SYMMETRIC) { json_object_set(key_members, "kty", json_object_get(key_export, "kty")); json_object_set(key_members, "k", json_object_get(key_export, "k")); } else if (type & R_KEY_TYPE_RSA) { json_object_set(key_members, "kty", json_object_get(key_export, "kty")); json_object_set(key_members, "e", json_object_get(key_export, "e")); json_object_set(key_members, "n", json_object_get(key_export, "n")); } else if (type & R_KEY_TYPE_EC) { json_object_set(key_members, "kty", json_object_get(key_export, "kty")); json_object_set(key_members, "crv", json_object_get(key_export, "crv")); json_object_set(key_members, "x", json_object_get(key_export, "x")); json_object_set(key_members, "y", json_object_get(key_export, "y")); } else if (type & R_KEY_TYPE_EDDSA || type & R_KEY_TYPE_ECDH) { json_object_set(key_members, "kty", json_object_get(key_export, "kty")); json_object_set(key_members, "crv", json_object_get(key_export, "crv")); json_object_set(key_members, "x", json_object_get(key_export, "x")); } else { type = R_KEY_TYPE_NONE; } if (type != R_KEY_TYPE_NONE) { key_dump = json_dumps(key_members, JSON_COMPACT|JSON_SORT_KEYS); if (key_dump != NULL) { if (!gnutls_hash_fast(alg, key_dump, o_strlen(key_dump), jwk_hash)) { if (o_base64url_encode(jwk_hash, (unsigned)gnutls_hash_get_len(alg), jwk_hash_b64, &jwk_hash_b64_len)) { thumb = o_strndup((const char *)jwk_hash_b64, jwk_hash_b64_len); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, error o_base64url_encode"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, error gnutls_hash_fast"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, error json_dumps key"); } o_free(key_dump); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, error invalid key type"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, error allocating resources for key_members"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_thumbprint, invalid hash option"); } json_decref(key_members); json_decref(key_export); return thumb; } static void scm_gnutls_certificate_status_to_c_string (gnutls_certificate_status_t c_obj) { static const struct { gnutls_certificate_status_t value; const char* name; } table[] = { { GNUTLS_CERT_INVALID, "invalid certificate" }, { GNUTLS_CERT_REVOKED, "revoked certificate" }, { GNUTLS_CERT_SIGNER_NOT_FOUND, "signer-not-found certificate" }, { GNUTLS_CERT_SIGNER_NOT_CA, "signer-not-ca certificate" }, { GNUTLS_CERT_INSECURE_ALGORITHM, "insecure-algorithm certificate" }, }; unsigned i; for (i = 0; i < 5; i++) { if (table[i].value & c_obj) { y_log_message(Y_LOG_LEVEL_DEBUG, "%s", table[i].name); } } } int r_jwk_validate_x5c_chain(jwk_t * jwk, int x5u_flags) { int ret, res; gnutls_certificate_status_t result; const char * cert; jwk_t * jwk_x5u = NULL; size_t cert_x509_len = 0, cert_x509_data_len, i; gnutls_x509_trust_list_t tlist = NULL; gnutls_x509_crt_t * cert_x509 = NULL, root_x509 = NULL; gnutls_datum_t cert_dat; struct _o_datum dat = {0, NULL}; if (jwk != NULL) { // Build cert_x509 chain if ((cert = r_jwk_get_property_str(jwk, "x5u")) != NULL) { if (r_jwk_init(&jwk_x5u) == RHN_OK) { if (r_jwk_import_from_x5u(jwk_x5u, x5u_flags, cert) == RHN_OK) { if (r_jwk_get_property_array_size(jwk_x5u, "x5c") > 0) { cert_x509_len = (size_t)r_jwk_get_property_array_size(jwk_x5u, "x5c"); cert_x509_data_len = cert_x509_len*sizeof(gnutls_x509_crt_t *); if ((cert_x509 = o_malloc(cert_x509_data_len)) != NULL) { memset(cert_x509, 0, cert_x509_data_len); ret = RHN_OK; for (i=0; i 0) { cert_x509_len = (size_t)r_jwk_get_property_array_size(jwk, "x5c"); cert_x509_data_len = cert_x509_len*sizeof(gnutls_x509_crt_t *); if ((cert_x509 = o_malloc(cert_x509_data_len)) != NULL) { memset(cert_x509, 0, cert_x509_data_len); ret = RHN_OK; for (i=0; i= 0) { if (gnutls_x509_trust_list_verify_crt(tlist, cert_x509, (unsigned int)cert_x509_len, 0, &result, NULL) >= 0) { if (result) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_validate_x5c_chain - certificate chain invalid"); scm_gnutls_certificate_status_to_c_string(result); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_validate_x5c_chain - Error gnutls_x509_trust_list_verify_crt"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_validate_x5c_chain - Error gnutls_x509_trust_list_add_cas"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwk_validate_x5c_chain - Error gnutls_x509_trust_list_init"); ret = RHN_ERROR; } gnutls_x509_trust_list_deinit(tlist, 0); } for (i=0; i * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include int _r_get_http_content(const char * url, int x5u_flags, const char * expected_content_type, struct _o_datum * datum); int r_jwks_init(jwks_t ** jwks) { int ret; if (jwks != NULL) { *jwks = json_pack("{s[]}", "keys"); ret = (*jwks!=NULL)?RHN_OK:RHN_ERROR_MEMORY; } else { ret = RHN_ERROR_PARAM; } return ret; } void r_jwks_free(jwks_t * jwks) { if (jwks != NULL) { json_decref(jwks); } } int r_jwks_is_valid(jwks_t * jwks) { int ret; json_t * jwk = NULL; size_t index = 0; if (jwks != NULL) { if (json_array_size(json_object_get(jwks, "keys"))) { json_array_foreach(json_object_get(jwks, "keys"), index, jwk) { if ((ret = r_jwk_is_valid(jwk)) != RHN_OK) { break; } } } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } size_t r_jwks_size(jwks_t * jwks) { if (jwks != NULL) { return json_array_size(json_object_get(jwks, "keys")); } else { return 0; } } jwk_t * r_jwks_get_at(jwks_t * jwks, size_t index) { if (jwks != NULL) { return json_deep_copy(json_array_get(json_object_get(jwks, "keys"), index)); } else { return NULL; } } jwk_t * r_jwks_get_by_kid(jwks_t * jwks, const char * kid) { json_t * jwk = NULL; size_t index = 0; if (jwks != NULL && !o_strnullempty(kid)) { json_array_foreach(json_object_get(jwks, "keys"), index, jwk) { if (0 == o_strcmp(kid, r_jwk_get_property_str(jwk, "kid"))) { return json_deep_copy(jwk); } } } return NULL; } jwks_t * r_jwks_copy(jwks_t * jwks) { if (jwks != NULL) { return json_deep_copy(jwks); } else { return NULL; } } int r_jwks_append_jwk(jwks_t * jwks, jwk_t * jwk) { if (jwks != NULL) { if (!json_array_append(json_object_get(jwks, "keys"), jwk)) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "rhonabwy jwks append - error json_array_append"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwks_set_at(jwks_t * jwks, size_t index, jwk_t * jwk) { if (jwks != NULL) { if (!json_array_set(json_object_get(jwks, "keys"), index, jwk)) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "rhonabwy jwks append - error json_array_set"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwks_remove_at(jwks_t * jwks, size_t index) { if (jwks != NULL) { if (!json_array_remove(json_object_get(jwks, "keys"), index)) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "rhonabwy jwks append - error json_array_remove"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwks_empty(jwks_t * jwks) { if (jwks != NULL) { if (!json_array_clear(json_object_get(jwks, "keys"))) { return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "rhonabwy jwks empty - error json_array_clear"); return RHN_ERROR; } } else { return RHN_ERROR_PARAM; } } int r_jwks_equal(jwks_t * jwks1, jwks_t * jwks2) { return json_equal(jwks1, jwks2); } char * r_jwks_export_to_json_str(jwks_t * jwks, int pretty) { char * str_jwk_export = NULL; if (jwks != NULL) { str_jwk_export = json_dumps(jwks, pretty?JSON_INDENT(2):JSON_COMPACT); } return str_jwk_export; } json_t * r_jwks_export_to_json_t(jwks_t * jwks) { if (jwks != NULL) { return json_deep_copy(jwks); } else { return NULL; } } gnutls_privkey_t * r_jwks_export_to_gnutls_privkey(jwks_t * jwks, size_t * len) { gnutls_privkey_t * ret = NULL; size_t i; jwk_t * jwk; if (jwks != NULL && len != NULL && r_jwks_size(jwks)) { if ((ret = o_malloc(r_jwks_size(jwks)*sizeof(gnutls_privkey_t))) != NULL) { *len = r_jwks_size(jwks); for (i=0; i<(*len); i++) { jwk = r_jwks_get_at(jwks, i); if ((ret[i] = r_jwk_export_to_gnutls_privkey(jwk)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "jwks export privkey - Error exporting privkey at index %zu", i); } r_jwk_free(jwk); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "jwks export privkey - Error allocating resources for ret"); } } return ret; } gnutls_pubkey_t * r_jwks_export_to_gnutls_pubkey(jwks_t * jwks, size_t * len, int x5u_flags) { gnutls_pubkey_t * ret = NULL; size_t i; jwk_t * jwk; if (jwks != NULL && len != NULL && r_jwks_size(jwks)) { if ((ret = o_malloc(r_jwks_size(jwks)*sizeof(gnutls_pubkey_t))) != NULL) { *len = r_jwks_size(jwks); for (i=0; i<(*len); i++) { jwk = r_jwks_get_at(jwks, i); if ((ret[i] = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "jwks export pubkey - Error exporting pubkey at index %zu", i); } r_jwk_free(jwk); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "jwks export pubkey - Error allocating resources for ret"); } } return ret; } int r_jwks_export_to_pem_der(jwks_t * jwks, int format, unsigned char * output, size_t * output_len, int x5u_flags) { size_t array_len, i, cur_len; unsigned char * cur_output = output; int ret; jwk_t * jwk; if (jwks != NULL && output != NULL && output_len != NULL && (array_len = r_jwks_size(jwks))) { cur_len = *output_len; for (i=0; i * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include #include #include #include #include #include #include static json_t * r_jws_parse_protected(const unsigned char * header_b64url) { json_t * j_return = NULL; struct _o_datum dat = {0, NULL}; do { if (!o_base64url_decode_alloc(header_b64url, o_strlen((const char *)header_b64url), &dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_protected - Invalid base64"); break; } j_return = json_loadb((const char *)dat.data, dat.size, JSON_DECODE_ANY, NULL); } while(0); o_free(dat.data); return j_return; } static int r_jws_extract_header(jws_t * jws, json_t * j_header, uint32_t parse_flags, int x5u_flags) { int ret; jwk_t * jwk; if (json_is_object(j_header)) { ret = RHN_OK; if (json_object_get(j_header, "alg") != NULL) { if (0 != o_strcmp("HS256", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("HS384", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("HS512", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("RS256", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("RS384", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("RS512", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PS256", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PS384", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("PS512", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ES256", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ES384", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ES512", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("EdDSA", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("ES256K", json_string_value(json_object_get(j_header, "alg"))) && 0 != o_strcmp("none", json_string_value(json_object_get(j_header, "alg")))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_extract_header - Invalid alg"); ret = RHN_ERROR_PARAM; } else { jws->alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg"))); } } if (json_string_length(json_object_get(j_header, "jku")) && (parse_flags&R_PARSE_HEADER_JKU)) { if (r_jwks_import_from_uri(jws->jwks_pubkey, json_string_value(json_object_get(j_header, "jku")), x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_extract_header - Error loading jwks from uri %s", json_string_value(json_object_get(j_header, "jku"))); } } if (json_object_get(j_header, "jwk") != NULL && (parse_flags&R_PARSE_HEADER_JWK)) { r_jwk_init(&jwk); if (r_jwk_import_from_json_t(jwk, json_object_get(j_header, "jwk")) == RHN_OK && r_jwk_key_type(jwk, NULL, 0)&R_KEY_TYPE_PUBLIC) { if (r_jwks_append_jwk(jws->jwks_pubkey, jwk) != RHN_OK) { ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_extract_header - Error parsing header jwk"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } if (json_object_get(j_header, "x5u") != NULL && (parse_flags&R_PARSE_HEADER_X5U)) { r_jwk_init(&jwk); if (r_jwk_import_from_x5u(jwk, x5u_flags, json_string_value(json_object_get(j_header, "x5u"))) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, jwk) != RHN_OK) { ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_extract_header - Error importing x5u"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } if (json_object_get(j_header, "x5c") != NULL && (parse_flags&R_PARSE_HEADER_X5C)) { r_jwk_init(&jwk); if (r_jwk_import_from_x5c(jwk, json_string_value(json_array_get(json_object_get(j_header, "x5c"), 0))) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, jwk) != RHN_OK) { ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_extract_header - Error importing x5c"); ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); } } else { ret = RHN_ERROR_PARAM; } return ret; } static int r_jws_set_header_value(jws_t * jws, int force) { int ret = RHN_OK; char * header_str = NULL; struct _o_datum dat = {0, NULL}; if (jws != NULL) { if (jws->header_b64url == NULL || force) { if ((header_str = json_dumps(jws->j_header, JSON_COMPACT)) != NULL) { if (o_base64url_encode_alloc((const unsigned char *)header_str, o_strlen(header_str), &dat)) { o_free(jws->header_b64url); jws->header_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_header_value - Error o_base64url_encode header_str"); ret = RHN_ERROR; } o_free(header_str); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_header_value - Error json_dumps header_str"); ret = RHN_ERROR; } } } else { ret = RHN_ERROR_PARAM; } return ret; } static int r_jws_set_payload_value(jws_t * jws, int force) { int ret = RHN_OK, zip = 0; unsigned char * payload_to_set = NULL; size_t payload_to_set_len = 0; struct _o_datum dat = {0, NULL}; if (jws != NULL) { if (jws->payload_b64url == NULL || force) { if (jws->payload_len) { if (0 == o_strcmp("DEF", r_jws_get_header_str_value(jws, "zip"))) { zip = 1; if ((ret = _r_deflate_payload(jws->payload, jws->payload_len, &payload_to_set, &payload_to_set_len)) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_payload_value - Error _r_deflate_payload"); } } else { payload_to_set = jws->payload; payload_to_set_len = jws->payload_len; } if (ret == RHN_OK) { if (o_base64url_encode_alloc(payload_to_set, payload_to_set_len, &dat)) { o_free(jws->payload_b64url); jws->payload_b64url = (unsigned char *)o_strndup((const char *)dat.data, dat.size); o_free(dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_payload_value - Error o_base64url_encode payload"); ret = RHN_ERROR; } } if (zip) { o_free(payload_to_set); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_payload_value - Error empty payload"); ret = RHN_ERROR_PARAM; } } } else { ret = RHN_ERROR_PARAM; } return ret; } static int r_jws_set_token_values(jws_t * jws, int force) { int ret; if ((ret = r_jws_set_header_value(jws, force)) == RHN_OK) { ret = r_jws_set_payload_value(jws, force); } return ret; } static unsigned char * r_jws_sign_hmac(jws_t * jws, jwk_t * jwk) { int alg = GNUTLS_DIG_NULL; unsigned char * data = NULL, * key = NULL, * sig = NULL, * to_return = NULL; size_t key_len = 0, sig_len = 0; struct _o_datum dat_sig = {0, NULL}; if (jws->alg == R_JWA_ALG_HS256) { alg = GNUTLS_DIG_SHA256; } else if (jws->alg == R_JWA_ALG_HS384) { alg = GNUTLS_DIG_SHA384; } else if (jws->alg == R_JWA_ALG_HS512) { alg = GNUTLS_DIG_SHA512; } if (alg != GNUTLS_DIG_NULL) { sig_len = (unsigned)gnutls_hmac_get_len((gnutls_mac_algorithm_t)alg); sig = o_malloc(sig_len); key_len = o_strlen(r_jwk_get_property_str(jwk, "k")); if (key_len) { key = o_malloc(key_len); if (key != NULL) { if (r_jwk_export_to_symmetric_key(jwk, key, &key_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error r_jwk_export_to_symmetric_key"); o_free(key); key = NULL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error allocating resources for key"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error key invalid, 'k' empty"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error key invalid, 'alg' invalid"); } if (key != NULL && sig != NULL) { data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); if (!gnutls_hmac_fast((gnutls_mac_algorithm_t)alg, key, key_len, data, o_strlen((const char *)data), sig)) { if (o_base64url_encode_alloc(sig, sig_len, &dat_sig)) { to_return = (unsigned char*)o_strndup((const char *)dat_sig.data, dat_sig.size); o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error o_base64url_encode sig_b64"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_hmac - Error gnutls_hmac_fast"); } } o_free(data); o_free(sig); o_free(key); return to_return; } static unsigned char * r_jws_sign_rsa(jws_t * jws, jwk_t * jwk) { gnutls_privkey_t privkey = r_jwk_export_to_gnutls_privkey(jwk); gnutls_datum_t body_dat, sig_dat; unsigned char * to_return = NULL; int alg = GNUTLS_DIG_NULL, res; unsigned int flag = 0; struct _o_datum dat_sig = {0, NULL}; switch (jws->alg) { case R_JWA_ALG_RS256: alg = GNUTLS_DIG_SHA256; break; case R_JWA_ALG_RS384: alg = GNUTLS_DIG_SHA384; break; case R_JWA_ALG_RS512: alg = GNUTLS_DIG_SHA512; break; /* RSA-PSS signature is available with GnuTLS >= 3.6 */ #if GNUTLS_VERSION_NUMBER >= 0x030600 case R_JWA_ALG_PS256: alg = GNUTLS_SIGN_RSA_PSS_SHA256; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; case R_JWA_ALG_PS384: alg = GNUTLS_SIGN_RSA_PSS_SHA384; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; case R_JWA_ALG_PS512: alg = GNUTLS_SIGN_RSA_PSS_SHA512; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; #endif default: break; } if (privkey != NULL && GNUTLS_PK_RSA == gnutls_privkey_get_pk_algorithm(privkey, NULL)) { body_dat.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); body_dat.size = (unsigned int)o_strlen((const char *)body_dat.data); if (!(res = #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_sign_data2 #else gnutls_privkey_sign_data #endif (privkey, (gnutls_sign_algorithm_t)alg, flag, &body_dat, &sig_dat))) { if (o_base64url_encode_alloc(sig_dat.data, sig_dat.size, &dat_sig)) { to_return = (unsigned char*)o_strndup((const char *)dat_sig.data, dat_sig.size); o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_rsa - Error o_base64url_encode for to_return"); o_free(to_return); to_return = NULL; } gnutls_free(sig_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_rsa - Error gnutls_privkey_sign_data2, res %d", res); } o_free(body_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_rsa - Error extracting privkey"); } gnutls_privkey_deinit(privkey); return to_return; } static unsigned char * r_jws_sign_ecdsa(jws_t * jws, jwk_t * jwk) { #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t privkey = r_jwk_export_to_gnutls_privkey(jwk); gnutls_datum_t body_dat, sig_dat, r, s; unsigned char * binary_sig = NULL, * to_return = NULL; int alg = GNUTLS_DIG_NULL, res; unsigned int adj = 0; unsigned int r_padding = 0, s_padding = 0, r_out_padding = 0, s_out_padding = 0; size_t sig_size; struct _o_datum dat_sig = {0, NULL}; if (jws->alg == R_JWA_ALG_ES256) { alg = GNUTLS_DIG_SHA256; adj = 32; } else if (jws->alg == R_JWA_ALG_ES384) { alg = GNUTLS_DIG_SHA384; adj = 48; } else if (jws->alg == R_JWA_ALG_ES512) { alg = GNUTLS_DIG_SHA512; adj = 66; } if (privkey != NULL && GNUTLS_PK_EC == gnutls_privkey_get_pk_algorithm(privkey, NULL)) { body_dat.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); body_dat.size = (unsigned int)o_strlen((const char *)body_dat.data); if (!(res = gnutls_privkey_sign_data(privkey, (gnutls_digest_algorithm_t)alg, 0, &body_dat, &sig_dat))) { if (!gnutls_decode_rs_value(&sig_dat, &r, &s)) { if (r.size > adj) { r_padding = r.size - adj; } else if (r.size < adj) { r_out_padding = adj - r.size; } if (s.size > adj) { s_padding = s.size - adj; } else if (s.size < adj) { s_out_padding = adj - s.size; } sig_size = adj << 1; if ((binary_sig = o_malloc(sig_size)) != NULL) { memset(binary_sig, 0, sig_size); memcpy(binary_sig + r_out_padding, r.data + r_padding, r.size - r_padding); memcpy(binary_sig + (r.size - r_padding + r_out_padding) + s_out_padding, s.data + s_padding, (s.size - s_padding)); if (o_base64url_encode_alloc(binary_sig, sig_size, &dat_sig)) { to_return = (unsigned char*)o_strndup((const char *)dat_sig.data, dat_sig.size); o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_ecdsa - Error o_base64url_encode_alloc for dat_sig"); } o_free(binary_sig); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_ecdsa - Error allocating resources for binary_sig"); } gnutls_free(r.data); gnutls_free(s.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_ecdsa - Error gnutls_decode_rs_value"); } gnutls_free(sig_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_ecdsa - Error gnutls_privkey_sign_data: %d", res); } o_free(body_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_ecdsa - Error extracting privkey"); } gnutls_privkey_deinit(privkey); return to_return; #else (void)(jws); (void)(jwk); return NULL; #endif } static unsigned char * r_jws_sign_eddsa(jws_t * jws, jwk_t * jwk) { #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t privkey = r_jwk_export_to_gnutls_privkey(jwk); gnutls_datum_t body_dat, sig_dat; unsigned char * to_return = NULL; int res; struct _o_datum dat_sig = {0, NULL}; if (privkey != NULL && GNUTLS_PK_EDDSA_ED25519 == gnutls_privkey_get_pk_algorithm(privkey, NULL)) { body_dat.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); body_dat.size = (unsigned int)o_strlen((const char *)body_dat.data); if (!(res = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA512, 0, &body_dat, &sig_dat))) { if (o_base64url_encode_alloc(sig_dat.data, sig_dat.size, &dat_sig)) { to_return = (unsigned char*)o_strndup((const char *)dat_sig.data, dat_sig.size); o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_eddsa - Error o_base64url_encode_alloc for dat_sig"); } gnutls_free(sig_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_eddsa - Error gnutls_privkey_sign_data: %d", res); } o_free(body_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_eddsa - Error extracting privkey"); } gnutls_privkey_deinit(privkey); return to_return; #else (void)(jws); (void)(jwk); return NULL; #endif } #if 0 static unsigned char * r_jws_sign_es256k(jws_t * jws, jwk_t * jwk) { #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t privkey = r_jwk_export_to_gnutls_privkey(jwk); gnutls_datum_t body_dat, sig_dat; unsigned char * to_return = NULL; int res; struct _o_datum dat_sig = {0, NULL}; if (privkey != NULL && GNUTLS_PK_EC == gnutls_privkey_get_pk_algorithm(privkey, NULL)) { body_dat.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); body_dat.size = o_strlen((const char *)body_dat.data); if (!(res = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, &body_dat, &sig_dat))) { if (o_base64url_encode_alloc(sig_dat.data, sig_dat.size, &dat_sig)) { to_return = (unsigned char*)o_strndup((const char *)dat_sig.data, dat_sig.size); o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_es256k - Error o_base64url_encode for dat_sig"); } gnutls_free(sig_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_es256k - Error gnutls_privkey_sign_data: %d", res); } o_free(body_dat.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_sign_es256k - Error extracting privkey"); } gnutls_privkey_deinit(privkey); return to_return; #else (void)(jws); (void)(jwk); return NULL; #endif } #endif static int r_jws_verify_sig_hmac(jws_t * jws, jwk_t * jwk) { unsigned char * sig = r_jws_sign_hmac(jws, jwk); int ret; if (sig != NULL && 0 == o_strcmp((const char *)jws->signature_b64url, (const char *)sig)) { ret = RHN_OK; } else { ret = RHN_ERROR_INVALID; } o_free(sig); return ret; } static int r_jws_verify_sig_rsa(jws_t * jws, jwk_t * jwk, int x5u_flags) { int alg = GNUTLS_DIG_NULL, ret = RHN_OK; unsigned int flag = 0; gnutls_datum_t sig_dat = {NULL, 0}, data; gnutls_pubkey_t pubkey = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags); struct _o_datum dat_sig = {0, NULL}; data.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); data.size = (unsigned int)o_strlen((const char *)data.data); switch (jws->alg) { case R_JWA_ALG_RS256: alg = GNUTLS_DIG_SHA256; break; case R_JWA_ALG_RS384: alg = GNUTLS_DIG_SHA384; break; case R_JWA_ALG_RS512: alg = GNUTLS_DIG_SHA512; break; #if GNUTLS_VERSION_NUMBER >= 0x030600 case R_JWA_ALG_PS256: alg = GNUTLS_SIGN_RSA_PSS_SHA256; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; case R_JWA_ALG_PS384: alg = GNUTLS_SIGN_RSA_PSS_SHA384; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; case R_JWA_ALG_PS512: alg = GNUTLS_SIGN_RSA_PSS_SHA512; flag = GNUTLS_PRIVKEY_SIGN_FLAG_RSA_PSS; break; #endif default: break; } if (pubkey != NULL && GNUTLS_PK_RSA == gnutls_pubkey_get_pk_algorithm(pubkey, NULL)) { if (!o_strnullempty((const char *)jws->signature_b64url)) { if (o_base64url_decode_alloc(jws->signature_b64url, o_strlen((const char *)jws->signature_b64url), &dat_sig)) { sig_dat.data = dat_sig.data; sig_dat.size = (unsigned int)dat_sig.size; if (gnutls_pubkey_verify_data2(pubkey, (gnutls_sign_algorithm_t)alg, flag, &data, &sig_dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_rsa - Error invalid signature"); ret = RHN_ERROR_INVALID; } o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_rsa - Error o_base64url_decode_alloc for dat_sig"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_rsa - Error signature empty"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_rsa - Invalid public key"); ret = RHN_ERROR_PARAM; } o_free(data.data); gnutls_pubkey_deinit(pubkey); return ret; } static int r_jws_verify_sig_ecdsa(jws_t * jws, jwk_t * jwk, int x5u_flags) { #if GNUTLS_VERSION_NUMBER >= 0x030600 int alg = 0, ret = RHN_OK; gnutls_datum_t sig_dat = {NULL, 0}, r, s, data; gnutls_pubkey_t pubkey = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags); struct _o_datum dat_sig = {0, NULL}; data.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); data.size = (unsigned int)o_strlen((const char *)data.data); switch (jws->alg) { case R_JWA_ALG_ES256: alg = GNUTLS_SIGN_ECDSA_SHA256; break; case R_JWA_ALG_ES384: alg = GNUTLS_SIGN_ECDSA_SHA384; break; case R_JWA_ALG_ES512: alg = GNUTLS_SIGN_ECDSA_SHA512; break; default: break; } if (pubkey != NULL && GNUTLS_PK_EC == gnutls_pubkey_get_pk_algorithm(pubkey, NULL)) { if (!o_strnullempty((const char *)jws->signature_b64url)) { if (o_base64url_decode_alloc(jws->signature_b64url, o_strlen((const char *)jws->signature_b64url), &dat_sig)) { if (dat_sig.size == 64) { r.size = 32; r.data = dat_sig.data; s.size = 32; s.data = dat_sig.data + 32; } else if (dat_sig.size == 96) { r.size = 48; r.data = dat_sig.data; s.size = 48; s.data = dat_sig.data + 48; } else if (dat_sig.size == 132) { r.size = 66; r.data = dat_sig.data; s.size = 66; s.data = dat_sig.data + 66; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Error invalid signature length"); ret = RHN_ERROR_INVALID; } if (ret == RHN_OK) { if (!gnutls_encode_rs_value(&sig_dat, &r, &s)) { if (gnutls_pubkey_verify_data2(pubkey, (gnutls_sign_algorithm_t)alg, 0, &data, &sig_dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Error invalid signature"); ret = RHN_ERROR_INVALID; } if (sig_dat.data != NULL) { gnutls_free(sig_dat.data); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Error gnutls_encode_rs_value"); ret = RHN_ERROR; } } o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Error o_base64url_decode_alloc for dat_sig"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Error signature empty"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_ecdsa - Invalid public key"); ret = RHN_ERROR_PARAM; } o_free(data.data); gnutls_pubkey_deinit(pubkey); return ret; #else (void)(jws); (void)(jwk); (void)(x5u_flags); return RHN_ERROR_INVALID; #endif } static int r_jws_verify_sig_eddsa(jws_t * jws, jwk_t * jwk, int x5u_flags) { #if GNUTLS_VERSION_NUMBER >= 0x030600 int ret = RHN_OK; gnutls_datum_t sig_dat = {NULL, 0}, data; gnutls_pubkey_t pubkey = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags); struct _o_datum dat_sig = {0, NULL}; data.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); data.size = (unsigned int)o_strlen((const char *)data.data); if (pubkey != NULL && GNUTLS_PK_EDDSA_ED25519 == gnutls_pubkey_get_pk_algorithm(pubkey, NULL)) { if (!o_strnullempty((const char *)jws->signature_b64url)) { if (o_base64url_decode_alloc(jws->signature_b64url, o_strlen((const char *)jws->signature_b64url), &dat_sig)) { sig_dat.data = dat_sig.data; sig_dat.size = (unsigned int)dat_sig.size; if (gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_EDDSA_ED25519, 0, &data, &sig_dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_eddsa - Error invalid signature"); ret = RHN_ERROR_INVALID; } o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_eddsa - Error o_base64url_decode for dat_sig"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_eddsa - Error signature empty"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_eddsa - Invalid public key"); ret = RHN_ERROR_PARAM; } o_free(data.data); gnutls_pubkey_deinit(pubkey); return ret; #else (void)(jws); (void)(jwk); (void)(x5u_flags); return RHN_ERROR_INVALID; #endif } #if 0 static int r_jws_verify_sig_es256k(jws_t * jws, jwk_t * jwk, int x5u_flags) { #if GNUTLS_VERSION_NUMBER >= 0x030600 int ret = RHN_OK; gnutls_datum_t sig_dat = {NULL, 0}, data; gnutls_pubkey_t pubkey = r_jwk_export_to_gnutls_pubkey(jwk, x5u_flags); struct _o_datum dat_sig = {0, NULL}; data.data = (unsigned char *)msprintf("%s.%s", jws->header_b64url, jws->payload_b64url); data.size = o_strlen((const char *)data.data); if (pubkey != NULL && GNUTLS_PK_EC == gnutls_pubkey_get_pk_algorithm(pubkey, NULL)) { if (!o_strnullempty((const char *)jws->signature_b64url)) { if (o_base64url_decode_alloc(jws->signature_b64url, o_strlen((const char *)jws->signature_b64url), &dat_sig)) { sig_dat.data = dat_sig.data; sig_dat.size = dat_sig.size; if (gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA256, 0, &data, &sig_dat)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_es256k - Error invalid signature"); ret = RHN_ERROR_INVALID; } o_free(dat_sig.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_es256k - Error o_base64url_decode_alloc for dat_sig"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_es256k - Error signature empty"); ret = RHN_ERROR_INVALID; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_verify_sig_es256k - Invalid public key"); ret = RHN_ERROR_PARAM; } o_free(data.data); gnutls_pubkey_deinit(pubkey); return ret; #else (void)(jws); (void)(jwk); (void)(x5u_flags); return RHN_ERROR_INVALID; #endif } #endif static int _r_verify_signature(jws_t * jws, jwk_t * jwk, jwa_alg alg, int x5u_flags) { int ret; switch (alg) { case R_JWA_ALG_HS256: case R_JWA_ALG_HS384: case R_JWA_ALG_HS512: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_HMAC) { ret = r_jws_verify_sig_hmac(jws, jwk); } else { ret = RHN_ERROR_INVALID; } break; case R_JWA_ALG_RS256: case R_JWA_ALG_RS384: case R_JWA_ALG_RS512: case R_JWA_ALG_PS256: case R_JWA_ALG_PS384: case R_JWA_ALG_PS512: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_RSA) { ret = r_jws_verify_sig_rsa(jws, jwk, x5u_flags); } else { ret = RHN_ERROR_INVALID; } break; case R_JWA_ALG_ES256: case R_JWA_ALG_ES384: case R_JWA_ALG_ES512: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_EC) { ret = r_jws_verify_sig_ecdsa(jws, jwk, x5u_flags); } else { ret = RHN_ERROR_INVALID; } break; case R_JWA_ALG_EDDSA: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_EDDSA) { ret = r_jws_verify_sig_eddsa(jws, jwk, x5u_flags); } else { ret = RHN_ERROR_INVALID; } break; #if 0 case R_JWA_ALG_ES256K: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_EC) { ret = r_jws_verify_sig_es256k(jws, jwk, x5u_flags); } else { ret = RHN_ERROR_INVALID; } break; #endif default: ret = RHN_ERROR_INVALID; break; } return ret; } static unsigned char * _r_generate_signature(jws_t * jws, jwk_t * jwk, jwa_alg alg, int x5u_flags) { unsigned char * str_ret = NULL; int res; if (jws != NULL && (jwk != NULL || alg == R_JWA_ALG_NONE)) { switch (alg) { case R_JWA_ALG_HS256: case R_JWA_ALG_HS384: case R_JWA_ALG_HS512: if (r_jwk_key_type(jwk, NULL, x5u_flags) & R_KEY_TYPE_HMAC) { str_ret = r_jws_sign_hmac(jws, jwk); } break; case R_JWA_ALG_RS256: case R_JWA_ALG_RS384: case R_JWA_ALG_RS512: case R_JWA_ALG_PS256: case R_JWA_ALG_PS384: case R_JWA_ALG_PS512: res = r_jwk_key_type(jwk, NULL, x5u_flags); if (res & R_KEY_TYPE_RSA && res &R_KEY_TYPE_PRIVATE) { str_ret = r_jws_sign_rsa(jws, jwk); } break; case R_JWA_ALG_ES256: case R_JWA_ALG_ES384: case R_JWA_ALG_ES512: res = r_jwk_key_type(jwk, NULL, x5u_flags); if (res & R_KEY_TYPE_EC && res & R_KEY_TYPE_PRIVATE) { str_ret = r_jws_sign_ecdsa(jws, jwk); } break; case R_JWA_ALG_EDDSA: res = r_jwk_key_type(jwk, NULL, x5u_flags); if (res & R_KEY_TYPE_EDDSA && res & R_KEY_TYPE_PRIVATE) { str_ret = r_jws_sign_eddsa(jws, jwk); } break; case R_JWA_ALG_NONE: str_ret = (unsigned char *)o_strdup(""); break; #if 0 case R_JWA_ALG_ES256K: res = r_jwk_key_type(jwk, NULL, x5u_flags); if (res & R_KEY_TYPE_EC && res & R_KEY_TYPE_PRIVATE) { str_ret = r_jws_sign_es256k(jws, jwk); } break; #endif default: y_log_message(Y_LOG_LEVEL_ERROR, "_r_generate_signature - Unsupported algorithm"); break; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_generate_signature - Error input parameters"); } return str_ret; } int r_jws_init(jws_t ** jws) { int ret; if (jws != NULL) { if ((*jws = o_malloc(sizeof(jws_t))) != NULL) { if (((*jws)->j_header = json_object()) != NULL) { if (r_jwks_init(&(*jws)->jwks_pubkey) == RHN_OK) { if (r_jwks_init(&(*jws)->jwks_privkey) == RHN_OK) { (*jws)->alg = R_JWA_ALG_UNKNOWN; (*jws)->header_b64url = NULL; (*jws)->payload_b64url = NULL; (*jws)->signature_b64url = NULL; (*jws)->payload = NULL; (*jws)->payload_len = 0; (*jws)->j_json_serialization = NULL; (*jws)->token_mode = R_JSON_MODE_COMPACT; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_init - Error allocating resources for jwks_privkey"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_init - Error allocating resources for jwks_pubkey"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_init - Error allocating resources for j_header"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_init - Error allocating resources for jws"); ret = RHN_ERROR_MEMORY; } } else { ret = RHN_ERROR_PARAM; } if (ret != RHN_OK && jws != NULL) { r_jws_free(*jws); *jws = NULL; } return ret; } void r_jws_free(jws_t * jws) { if (jws != NULL) { r_jwks_free(jws->jwks_privkey); r_jwks_free(jws->jwks_pubkey); o_free(jws->header_b64url); o_free(jws->payload_b64url); o_free(jws->signature_b64url); json_decref(jws->j_header); o_free(jws->payload); json_decref(jws->j_json_serialization); o_free(jws); } } jws_t * r_jws_copy(jws_t * jws) { jws_t * jws_copy = NULL; if (jws != NULL) { if (r_jws_init(&jws_copy) == RHN_OK) { if (r_jws_set_payload(jws_copy, jws->payload, jws->payload_len) == RHN_OK) { jws_copy->header_b64url = (unsigned char *)o_strdup((const char *)jws->header_b64url); jws_copy->payload_b64url = (unsigned char *)o_strdup((const char *)jws->payload_b64url); jws_copy->signature_b64url = (unsigned char *)o_strdup((const char *)jws->signature_b64url); jws_copy->alg = jws->alg; r_jwks_free(jws_copy->jwks_privkey); jws_copy->jwks_privkey = r_jwks_copy(jws->jwks_privkey); r_jwks_free(jws_copy->jwks_pubkey); jws_copy->jwks_pubkey = r_jwks_copy(jws->jwks_pubkey); json_decref(jws_copy->j_header); jws_copy->j_header = json_deep_copy(jws->j_header); jws_copy->j_json_serialization = json_deep_copy(jws->j_json_serialization); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_copy - Error allocating resources for jws_copy->payload"); r_jws_free(jws_copy); jws_copy = NULL; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_copy - Error r_jws_init"); } } return jws_copy; } int r_jws_set_payload(jws_t * jws, const unsigned char * payload, size_t payload_len) { int ret; if (jws != NULL) { o_free(jws->payload); if (payload != NULL && payload_len) { if ((jws->payload = o_malloc(payload_len)) != NULL) { memcpy(jws->payload, payload, payload_len); jws->payload_len = payload_len; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_payload - Error allocating resources for payload"); ret = RHN_ERROR_MEMORY; } } else { jws->payload = NULL; jws->payload_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jws_get_payload(jws_t * jws, size_t * payload_len) { if (jws != NULL) { if (payload_len != NULL) { *payload_len = jws->payload_len; } return jws->payload; } return NULL; } int r_jws_set_alg(jws_t * jws, jwa_alg alg) { int ret = RHN_OK; if (jws != NULL) { switch (alg) { case R_JWA_ALG_NONE: json_object_set_new(jws->j_header, "alg", json_string("none")); break; case R_JWA_ALG_HS256: json_object_set_new(jws->j_header, "alg", json_string("HS256")); break; case R_JWA_ALG_HS384: json_object_set_new(jws->j_header, "alg", json_string("HS384")); break; case R_JWA_ALG_HS512: json_object_set_new(jws->j_header, "alg", json_string("HS512")); break; case R_JWA_ALG_RS256: json_object_set_new(jws->j_header, "alg", json_string("RS256")); break; case R_JWA_ALG_RS384: json_object_set_new(jws->j_header, "alg", json_string("RS384")); break; case R_JWA_ALG_RS512: json_object_set_new(jws->j_header, "alg", json_string("RS512")); break; case R_JWA_ALG_ES256: json_object_set_new(jws->j_header, "alg", json_string("ES256")); break; case R_JWA_ALG_ES384: json_object_set_new(jws->j_header, "alg", json_string("ES384")); break; case R_JWA_ALG_ES512: json_object_set_new(jws->j_header, "alg", json_string("ES512")); break; case R_JWA_ALG_PS256: json_object_set_new(jws->j_header, "alg", json_string("PS256")); break; case R_JWA_ALG_PS384: json_object_set_new(jws->j_header, "alg", json_string("PS384")); break; case R_JWA_ALG_PS512: json_object_set_new(jws->j_header, "alg", json_string("PS512")); break; case R_JWA_ALG_EDDSA: json_object_set_new(jws->j_header, "alg", json_string("EdDSA")); break; case R_JWA_ALG_ES256K: json_object_set_new(jws->j_header, "alg", json_string("ES256K")); break; default: ret = RHN_ERROR_PARAM; break; } if (ret == RHN_OK) { jws->alg = alg; } } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_alg r_jws_get_alg(jws_t * jws) { if (jws != NULL) { return jws->alg; } else { return R_JWA_ALG_UNKNOWN; } } const char * r_jws_get_kid(jws_t * jws) { const char * kid = r_jws_get_header_str_value(jws, "kid"); if (!!o_strnullempty(kid)) { if (jws != NULL && jws->token_mode == R_JSON_MODE_FLATTENED) { kid = json_string_value(json_object_get(json_object_get(jws->j_json_serialization, "header"), "kid")); } } return kid; } int r_jws_set_header_str_value(jws_t * jws, const char * key, const char * str_value) { int ret; if (jws != NULL) { if ((ret = _r_json_set_str_value(jws->j_header, key, str_value)) == RHN_OK) { o_free(jws->header_b64url); jws->header_b64url = NULL; } return ret; } else { return RHN_ERROR_PARAM; } } int r_jws_set_header_int_value(jws_t * jws, const char * key, rhn_int_t i_value) { int ret; if (jws != NULL) { if ((ret = _r_json_set_int_value(jws->j_header, key, i_value)) == RHN_OK) { o_free(jws->header_b64url); jws->header_b64url = NULL; } return ret; } else { return RHN_ERROR_PARAM; } } int r_jws_set_header_json_t_value(jws_t * jws, const char * key, json_t * j_value) { int ret; if (jws != NULL) { if ((ret = _r_json_set_json_t_value(jws->j_header, key, j_value)) == RHN_OK) { o_free(jws->header_b64url); jws->header_b64url = NULL; } return ret; } else { ret = RHN_ERROR_PARAM; } return ret; } const char * r_jws_get_header_str_value(jws_t * jws, const char * key) { if (jws != NULL) { return _r_json_get_str_value(jws->j_header, key); } return NULL; } rhn_int_t r_jws_get_header_int_value(jws_t * jws, const char * key) { if (jws != NULL) { return _r_json_get_int_value(jws->j_header, key); } return 0; } json_t * r_jws_get_header_json_t_value(jws_t * jws, const char * key) { if (jws != NULL) { return _r_json_get_json_t_value(jws->j_header, key); } return NULL; } json_t * r_jws_get_full_header_json_t(jws_t * jws) { if (jws != NULL) { return _r_json_get_full_json_t(jws->j_header); } return NULL; } char * r_jws_get_full_header_str(jws_t * jws) { char * to_return = NULL; if (jws != NULL) { to_return = json_dumps(jws->j_header, JSON_COMPACT); } return to_return; } int r_jws_add_keys(jws_t * jws, jwk_t * jwk_privkey, jwk_t * jwk_pubkey) { int ret = RHN_OK; jwa_alg alg; if (jws != NULL && (jwk_privkey != NULL || jwk_pubkey != NULL)) { if (jwk_privkey != NULL) { if (r_jwks_append_jwk(jws->jwks_privkey, jwk_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys - Error setting jwk_privkey"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } if (jwk_pubkey != NULL) { if (r_jwks_append_jwk(jws->jwks_pubkey, jwk_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys - Error setting jwk_pubkey"); ret = RHN_ERROR; } } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_add_jwks(jws_t * jws, jwks_t * jwks_privkey, jwks_t * jwks_pubkey) { size_t i; int ret, res; jwk_t * jwk; if (jws != NULL && (jwks_privkey != NULL || jwks_pubkey != NULL)) { ret = RHN_OK; if (jwks_privkey != NULL) { for (i=0; ret==RHN_OK && ijwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_str - Error setting privkey"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_str - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_str(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_str - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_str - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_add_keys_json_t(jws_t * jws, json_t * privkey, json_t * pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jws != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_json_t(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_t - Error setting privkey"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_t - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_t(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_t - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_json_t - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_add_keys_pem_der(jws_t * jws, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jws != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_pem_der(j_privkey, R_X509_TYPE_PRIVKEY, format, privkey, privkey_len) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_pem_der - Error setting privkey"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_pem_der - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_pem_der(j_pubkey, R_X509_TYPE_PUBKEY, format, pubkey, pubkey_len) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_pem_der - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_pem_der - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_add_keys_gnutls(jws_t * jws, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jws != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_gnutls_privkey(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_privkey, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_gnutls - Error setting privkey"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_gnutls - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_gnutls_pubkey(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_pubkey, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_gnutls - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_keys_gnutls - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_add_key_symmetric(jws_t * jws, const unsigned char * key, size_t key_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_key = NULL; if (jws != NULL && key != NULL && key_len) { if (r_jwk_init(&j_key) == RHN_OK && r_jwk_import_from_symmetric_key(j_key, key, key_len) == RHN_OK) { if (r_jwks_append_jwk(jws->jwks_privkey, j_key) != RHN_OK || r_jwks_append_jwk(jws->jwks_pubkey, j_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_sign_key_symmetric - Error setting key"); ret = RHN_ERROR; } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_key, "alg"))) != R_JWA_ALG_NONE) { r_jws_set_alg(jws, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_add_sign_key_symmetric - Error parsing key"); ret = RHN_ERROR; } r_jwk_free(j_key); } else { ret = RHN_ERROR_PARAM; } return ret; } jwks_t * r_jws_get_jwks_privkey(jws_t * jws) { if (jws != NULL) { return r_jwks_copy(jws->jwks_privkey); } else { return NULL; } } jwks_t * r_jws_get_jwks_pubkey(jws_t * jws) { if (jws != NULL) { return r_jwks_copy(jws->jwks_pubkey); } else { return NULL; } } int r_jws_parse(jws_t * jws, const char * jws_str, int x5u_flags) { return r_jws_parsen(jws, jws_str, o_strlen(jws_str), x5u_flags); } int r_jws_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags) { return r_jws_advanced_parsen(jws, jws_str, jws_str_len, R_PARSE_HEADER_ALL, x5u_flags); } int r_jws_parse_unsecure(jws_t * jws, const char * jws_str, int x5u_flags) { return r_jws_parsen_unsecure(jws, jws_str, o_strlen(jws_str), x5u_flags); } int r_jws_parsen_unsecure(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags) { return r_jws_advanced_parsen(jws, jws_str, jws_str_len, R_PARSE_ALL, x5u_flags); } int r_jws_advanced_parse(jws_t * jws, const char * jws_str, uint32_t parse_flags, int x5u_flags) { return r_jws_advanced_parsen(jws, jws_str, o_strlen(jws_str), parse_flags, x5u_flags); } int r_jws_advanced_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags) { int ret; char * str = (char *)jws_str; if (jws != NULL && str != NULL && jws_str_len) { while(isspace((unsigned char)*str) && jws_str_len) { str++; jws_str_len--; } if (0 == o_strncmp("ey", str, 2)) { ret = r_jws_advanced_compact_parsen(jws, jws_str, jws_str_len, parse_flags, x5u_flags); } else if (*str == '{') { ret = r_jws_advanced_parsen_json_str(jws, jws_str, jws_str_len, parse_flags, x5u_flags); } else { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_compact_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags) { int ret = r_jws_compact_parsen_unsecure(jws, jws_str, jws_str_len, x5u_flags); if (ret == RHN_OK) { if (r_jws_get_alg(jws) != R_JWA_ALG_NONE) { return RHN_OK; } else { return RHN_ERROR_INVALID; } } else { return ret; } } int r_jws_compact_parse(jws_t * jws, const char * jws_str, int x5u_flags) { return r_jws_compact_parsen_unsecure(jws, jws_str, o_strlen(jws_str), x5u_flags); } int r_jws_compact_parsen_unsecure(jws_t * jws, const char * jws_str, size_t jws_str_len, int x5u_flags) { return r_jws_advanced_compact_parsen(jws, jws_str, jws_str_len, R_PARSE_ALL, x5u_flags); } int r_jws_compact_parse_unsecure(jws_t * jws, const char * jws_str, int x5u_flags) { return r_jws_compact_parsen_unsecure(jws, jws_str, o_strlen(jws_str), x5u_flags); } int r_jws_advanced_compact_parse(jws_t * jws, const char * jws_str, uint32_t parse_flags, int x5u_flags) { return r_jws_advanced_compact_parsen(jws, jws_str, o_strlen(jws_str), parse_flags, x5u_flags); } int r_jws_advanced_compact_parsen(jws_t * jws, const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags) { int ret; char ** str_array = NULL; char * token = NULL; size_t split_size = 0, unzip_len = 0; json_t * j_header = NULL; struct _o_datum dat_header = {0, NULL}, dat_payload = {0, NULL}; unsigned char * unzip = NULL; if (jws != NULL && jws_str != NULL && jws_str_len) { token = o_strndup(jws_str, jws_str_len); if ((split_size = split_string(token, ".", &str_array)) == 2 || split_size == 3) { // Check if all first 2 elements are base64url if (o_base64url_decode_alloc((unsigned char *)str_array[0], o_strlen(str_array[0]), &dat_header) && o_base64url_decode_alloc((unsigned char *)str_array[1], o_strlen(str_array[1]), &dat_payload)) { ret = RHN_OK; do { // Decode header j_header = json_loadb((const char*)dat_header.data, dat_header.size, JSON_DECODE_ANY, NULL); if (r_jws_extract_header(jws, j_header, parse_flags, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error extracting header params"); ret = RHN_ERROR_PARAM; break; } json_decref(jws->j_header); jws->j_header = json_incref(j_header); if (!(parse_flags&R_PARSE_UNSIGNED)) { if (r_jws_get_alg(jws) == R_JWA_ALG_NONE) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error unsigned jws"); ret = RHN_ERROR_INVALID; break; } } // Decode payload if (0 == o_strcmp("DEF", r_jws_get_header_str_value(jws, "zip"))) { if (_r_inflate_payload(dat_payload.data, dat_payload.size, &unzip, &unzip_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error _r_inflate_payload"); ret = RHN_ERROR_PARAM; break; } if (r_jws_set_payload(jws, unzip, unzip_len) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error r_jws_set_payload"); ret = RHN_ERROR_PARAM; break; } } else { if (r_jws_set_payload(jws, dat_payload.data, dat_payload.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - Error r_jws_set_payload"); ret = RHN_ERROR; break; } } o_free(jws->header_b64url); jws->header_b64url = (unsigned char *)o_strdup(str_array[0]); o_free(jws->signature_b64url); jws->signature_b64url = NULL; if (str_array[2] != NULL) { jws->signature_b64url = (unsigned char *)o_strdup(str_array[2]); } if (r_jws_get_alg(jws) != R_JWA_ALG_NONE && o_strnullempty(str_array[2])) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error invalid signature length"); ret = RHN_ERROR_PARAM; break; } } while (0); json_decref(j_header); o_free(unzip); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - error decoding jws from base64url format"); ret = RHN_ERROR_PARAM; } o_free(dat_header.data); o_free(dat_payload.data); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_advanced_compact_parsen - jws_str invalid format"); ret = RHN_ERROR_PARAM; } free_string_array(str_array); o_free(token); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jws_parse_json_t(jws_t * jws, json_t * jws_json, int x5u_flags) { return r_jws_advanced_parse_json_t(jws, jws_json, R_PARSE_HEADER_ALL, x5u_flags); } int r_jws_parsen_json_str(jws_t * jws, const char * jws_json_str, size_t jws_str_len, int x5u_flags) { json_t * jws_json = NULL; int ret; jws_json = json_loadb(jws_json_str, jws_str_len, JSON_DECODE_ANY, NULL); ret = r_jws_parse_json_t(jws, jws_json, x5u_flags); json_decref(jws_json); return ret; } int r_jws_parse_json_str(jws_t * jws, const char * jws_json_str, int x5u_flags) { return r_jws_parsen_json_str(jws, jws_json_str, o_strlen(jws_json_str), x5u_flags); } int r_jws_advanced_parse_json_str(jws_t * jws, const char * jws_json_str, uint32_t parse_flags, int x5u_flags) { return r_jws_advanced_parsen_json_str(jws, jws_json_str, o_strlen(jws_json_str), parse_flags, x5u_flags); } int r_jws_advanced_parsen_json_str(jws_t * jws, const char * jws_json_str, size_t jws_json_str_len, uint32_t parse_flags, int x5u_flags) { json_t * jws_json = NULL; int ret; jws_json = json_loadb(jws_json_str, jws_json_str_len, JSON_DECODE_ANY, NULL); ret = r_jws_advanced_parse_json_t(jws, jws_json, parse_flags, x5u_flags); json_decref(jws_json); return ret; } int r_jws_advanced_parse_json_t(jws_t * jws, json_t * jws_json, uint32_t parse_flags, int x5u_flags) { int ret; size_t index = 0, signature_len = 0, header_len = 0; char * str_header = NULL; json_t * j_header = NULL, * j_element = NULL; struct _o_datum dat_header = {0, NULL}, dat_payload = {0, NULL}; if (jws != NULL && json_is_object(jws_json)) { if (json_string_length(json_object_get(jws_json, "payload"))) { if (json_string_length(json_object_get(jws_json, "protected"))) { // Mode flattened - 1 signature maximum ret = RHN_OK; jws->token_mode = R_JSON_MODE_FLATTENED; do { json_decref(jws->j_json_serialization); if ((jws->j_json_serialization = json_deep_copy(jws_json)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting j_json_serialization"); ret = RHN_ERROR; break; } o_free(jws->header_b64url); if ((jws->header_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jws_json, "protected")))) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting header_b64url"); ret = RHN_ERROR; break; } o_free(jws->payload_b64url); if ((jws->payload_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jws_json, "payload")))) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting payload_b64url"); ret = RHN_ERROR; break; } o_free(jws->signature_b64url); if (json_string_length(json_object_get(jws_json, "signature"))) { if ((jws->signature_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jws_json, "signature")))) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting signature_b64url"); ret = RHN_ERROR; break; } if (!o_base64url_decode((unsigned char *)jws->signature_b64url, o_strlen((const char *)jws->signature_b64url), NULL, &signature_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Invalid JWS, signature not valid base64url format"); ret = RHN_ERROR_PARAM; break; } } else { jws->signature_b64url = NULL; } // Decode header if (!o_base64url_decode_alloc((unsigned char *)jws->header_b64url, o_strlen((const char *)jws->header_b64url), &dat_header)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error decoding str_header"); ret = RHN_ERROR_PARAM; break; } j_header = json_loadb((const char*)dat_header.data, dat_header.size, JSON_DECODE_ANY, NULL); if (r_jws_extract_header(jws, j_header, parse_flags, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error extracting header params"); ret = RHN_ERROR_PARAM; break; } json_decref(jws->j_header); jws->j_header = json_incref(j_header); // Decode payload if (!o_base64url_decode_alloc((unsigned char *)jws->payload_b64url, o_strlen((const char *)jws->payload_b64url), &dat_payload)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error decoding payload"); ret = RHN_ERROR_PARAM; break; } if (r_jws_set_payload(jws, dat_payload.data, dat_payload.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error r_jws_set_payload"); ret = RHN_ERROR; break; } if (r_jws_extract_header(jws, json_object_get(jws_json, "header"), parse_flags, x5u_flags) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error extracting header params"); ret = RHN_ERROR_PARAM; break; } } while (0); json_decref(j_header); o_free(dat_header.data); o_free(dat_payload.data); } else { ret = RHN_OK; if (json_array_size(json_object_get(jws_json, "signatures"))) { json_array_foreach(json_object_get(jws_json, "signatures"), index, j_element) { if (!json_string_length(json_object_get(j_element, "protected")) || !json_string_length(json_object_get(j_element, "signature"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error invalid format, a signature object must contain string elements 'protected' and 'signature'"); ret = RHN_ERROR_PARAM; break; } if (json_object_get(j_element, "header") && !json_is_object(json_object_get(j_element, "header"))) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error invalid format, the 'header property in a signature object must be a JSON object"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(j_element, "protected")), json_string_length(json_object_get(j_element, "protected")), NULL, &header_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error header base64url format"); ret = RHN_ERROR_PARAM; break; } if (!o_base64url_decode((const unsigned char *)json_string_value(json_object_get(j_element, "signature")), json_string_length(json_object_get(j_element, "signature")), NULL, &signature_len)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error signature base64url format"); ret = RHN_ERROR_PARAM; break; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error invalid format, signatures must be a JSON array"); ret = RHN_ERROR_PARAM; } if (ret == RHN_OK) { // Mode general - multiple signatures allowed jws->token_mode = R_JSON_MODE_GENERAL; do { o_free(jws->header_b64url); jws->header_b64url = NULL; o_free(jws->signature_b64url); jws->signature_b64url = NULL; json_decref(jws->j_json_serialization); if ((jws->j_json_serialization = json_deep_copy(jws_json)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting j_json_serialization"); ret = RHN_ERROR; break; } o_free(jws->payload_b64url); if ((jws->payload_b64url = (unsigned char *)o_strdup(json_string_value(json_object_get(jws_json, "payload")))) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error setting payload_b64url"); ret = RHN_ERROR; break; } // Decode payload if (!o_base64url_decode_alloc((unsigned char *)jws->payload_b64url, o_strlen((const char *)jws->payload_b64url), &dat_payload)) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - error decoding jws->payload"); ret = RHN_ERROR_PARAM; break; } if (r_jws_set_payload(jws, dat_payload.data, dat_payload.size) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error r_jws_set_payload"); ret = RHN_ERROR; break; } } while (0); json_decref(j_header); o_free(str_header); o_free(dat_payload.data); } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error payload missing"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_parse_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } jws_t * r_jws_quick_parse(const char * jws_str, uint32_t parse_flags, int x5u_flags) { return r_jws_quick_parsen(jws_str, o_strlen(jws_str), parse_flags, x5u_flags); } jws_t * r_jws_quick_parsen(const char * jws_str, size_t jws_str_len, uint32_t parse_flags, int x5u_flags) { jws_t * jws = NULL; int ret; if (r_jws_init(&jws) == RHN_OK) { ret = r_jws_advanced_parsen(jws, jws_str, jws_str_len, parse_flags, x5u_flags); if (ret != RHN_OK) { r_jws_free(jws); jws = NULL; } } else { r_jws_free(jws); jws = NULL; } return jws; } int r_jws_verify_signature(jws_t * jws, jwk_t * jwk_pubkey, int x5u_flags) { int ret, res; jwk_t * jwk = NULL, * cur_jwk; const char * kid; json_t * j_signature = NULL, * j_header; size_t index = 0, i; if (jws != NULL) { if (jwk_pubkey != NULL) { jwk = r_jwk_copy(jwk_pubkey); } else { if ((kid = r_jws_get_header_str_value(jws, "kid")) != NULL || (jws->token_mode == R_JSON_MODE_FLATTENED && (kid = json_string_value(json_object_get(json_object_get(jws->j_json_serialization, "header"), "kid"))) != NULL)) { jwk = r_jwks_get_by_kid(jws->jwks_pubkey, kid); } else if (r_jwks_size(jws->jwks_pubkey) == 1) { jwk = r_jwks_get_at(jws->jwks_pubkey, 0); } } } if (jws != NULL) { if (jws->token_mode == R_JSON_MODE_GENERAL) { ret = RHN_ERROR_INVALID; o_free(jws->header_b64url); o_free(jws->signature_b64url); json_array_foreach(json_object_get(jws->j_json_serialization, "signatures"), index, j_signature) { jws->header_b64url = (unsigned char *)json_string_value(json_object_get(j_signature, "protected")); jws->signature_b64url = (unsigned char *)json_string_value(json_object_get(j_signature, "signature")); kid = json_string_value(json_object_get(json_object_get(j_signature, "header"), "kid")); if ((j_header = r_jws_parse_protected((const unsigned char *)json_string_value(json_object_get(j_signature, "protected")))) != NULL) { res = r_jws_extract_header(jws, j_header, R_PARSE_NONE, x5u_flags); json_decref(j_header); if (res == RHN_OK) { if (!o_strnullempty(kid)) { if (jwk_pubkey != NULL) { ret = _r_verify_signature(jws, jwk, jws->alg, x5u_flags); } else { if ((cur_jwk = r_jwks_get_by_kid(jws->jwks_pubkey, kid)) != NULL) { ret = _r_verify_signature(jws, cur_jwk, jws->alg, x5u_flags); r_jwk_free(cur_jwk); } } if (ret != RHN_ERROR_INVALID) { break; } } else { if (jwk_pubkey != NULL) { if ((ret = _r_verify_signature(jws, jwk_pubkey, jws->alg, x5u_flags)) != RHN_ERROR_INVALID) { break; } } else if (r_jwks_size(jws->jwks_pubkey)) { for (i=0; ijwks_pubkey); i++) { cur_jwk = r_jwks_get_at(jws->jwks_pubkey, i); ret = _r_verify_signature(jws, cur_jwk, jws->alg, x5u_flags); r_jwk_free(cur_jwk); if (ret != RHN_ERROR_INVALID) { break; } } if (ret != RHN_ERROR_INVALID) { break; } } } } else { ret = RHN_ERROR; break; } } else { ret = RHN_ERROR; break; } } jws->header_b64url = NULL; jws->signature_b64url = NULL; } else { if (r_jws_set_token_values(jws, 0) == RHN_OK && jws->signature_b64url != NULL) { if (jwk != NULL) { ret = _r_verify_signature(jws, jwk, jws->alg, x5u_flags); } else { ret = RHN_ERROR_INVALID; } } else { ret = RHN_ERROR_PARAM; } } } else { ret = RHN_ERROR_PARAM; } r_jwk_free(jwk); return ret; } char * r_jws_serialize(jws_t * jws, jwk_t * jwk_privkey, int x5u_flags) { if (r_jws_get_alg(jws) != R_JWA_ALG_NONE) { return r_jws_serialize_unsecure(jws, jwk_privkey, x5u_flags); } else { return NULL; } } char * r_jws_serialize_unsecure(jws_t * jws, jwk_t * jwk_privkey, int x5u_flags) { jwk_t * jwk = NULL; char * jws_str = NULL; jwa_alg alg; if (jws != NULL) { if (jwk_privkey != NULL) { jwk = r_jwk_copy(jwk_privkey); if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk, "alg"))) != R_JWA_ALG_NONE && alg != R_JWA_ALG_UNKNOWN) { r_jws_set_alg(jws, alg); } } else { if (r_jws_get_header_str_value(jws, "kid") != NULL) { jwk = r_jwks_get_by_kid(jws->jwks_privkey, r_jws_get_header_str_value(jws, "kid")); } else if (jws != NULL && r_jwks_size(jws->jwks_privkey) == 1) { jwk = r_jwks_get_at(jws->jwks_privkey, 0); } if (jws->alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk, "alg"))) != R_JWA_ALG_NONE && alg != R_JWA_ALG_UNKNOWN) { r_jws_set_alg(jws, alg); } } if (r_jwk_get_property_str(jwk, "kid") != NULL && r_jws_get_header_str_value(jws, "kid") == NULL) { r_jws_set_header_str_value(jws, "kid", r_jwk_get_property_str(jwk, "kid")); } o_free(jws->signature_b64url); if (r_jws_set_token_values(jws, 1) == RHN_OK) { jws->signature_b64url = _r_generate_signature(jws, jwk, jws->alg, x5u_flags); if (jws->signature_b64url != NULL) { jws_str = msprintf("%s.%s.%s", jws->header_b64url, jws->payload_b64url, jws->signature_b64url); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize - No signature"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize - Error r_jws_set_token_values"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize - Error input parameters"); } r_jwk_free(jwk); return jws_str; } char * r_jws_serialize_json_str(jws_t * jws, jwks_t * jwks_privkey, int x5u_flags, int mode) { json_t * j_result = r_jws_serialize_json_t(jws, jwks_privkey, x5u_flags, mode); char * str_result = json_dumps(j_result, JSON_COMPACT); json_decref(j_result); return str_result; } json_t * r_jws_serialize_json_t(jws_t * jws, jwks_t * jwks_privkey, int x5u_flags, int mode) { json_t * j_return = NULL, * j_signature; jwk_t * jwk = NULL; jwa_alg alg; const char * kid; unsigned char * signature = NULL; size_t i = 0; if (jwks_privkey == NULL) { jwks_privkey = jws->jwks_privkey; } if (jws != NULL && r_jwks_size(jwks_privkey)) { jws->token_mode = mode; if (mode == R_JSON_MODE_FLATTENED) { if ((kid = r_jws_get_header_str_value(jws, "kid")) != NULL) { jwk = r_jwks_get_by_kid(jwks_privkey, r_jws_get_header_str_value(jws, "kid")); } else { jwk = r_jwks_get_at(jwks_privkey, 0); kid = r_jwk_get_property_str(jwk, "kid"); } if ((alg = jws->alg) == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(jwk, "alg"))) != R_JWA_ALG_NONE && alg != R_JWA_ALG_UNKNOWN) { r_jws_set_alg(jws, alg); } if (r_jws_set_token_values(jws, 1) == RHN_OK) { if ((signature = _r_generate_signature(jws, jwk, alg, x5u_flags)) != NULL) { j_return = json_pack("{ssssss}", "payload", jws->payload_b64url, "protected", jws->header_b64url, "signature", signature); if (kid != NULL) { json_object_set_new(j_return, "header", json_pack("{ss}", "kid", kid)); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error _r_generate_signature"); } o_free(signature); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error r_jws_set_header_value"); } r_jwk_free(jwk); } else { if (r_jws_set_payload_value(jws, 1) == RHN_OK) { j_return = json_pack("{sss[]}", "payload", jws->payload_b64url, "signatures"); for (i=0; iheader_b64url, "signature", signature); if (kid != NULL) { json_object_set_new(j_signature, "header", json_pack("{ss}", "kid", kid)); } json_array_append_new(json_object_get(j_return, "signatures"), j_signature); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error _r_generate_signature"); } o_free(signature); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error generating protected header at index %zu", i); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Invalid jwk at index %zu, no alg specified", i); } r_jwk_free(jwk); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error r_jws_set_header_value"); } } json_decref(jws->j_json_serialization); jws->j_json_serialization = json_deep_copy(j_return); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_serialize_json_t - Error input parameters"); } return j_return; } int r_jws_set_full_header_json_t(jws_t * jws, json_t * j_header) { int ret = RHN_OK; jwa_alg alg; if (jws != NULL && json_is_object(j_header)) { if (json_object_get(j_header, "alg") != NULL) { if ((alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg")))) != R_JWA_ALG_UNKNOWN) { jws->alg = alg; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_full_header_json_t - Error invalid alg parameter"); ret = RHN_ERROR_PARAM; } } if (ret == RHN_OK) { json_decref(jws->j_header); if ((jws->j_header = json_deep_copy(j_header)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_full_header_json_t - Error setting header"); ret = RHN_ERROR_MEMORY; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_full_header_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jws_set_full_header_json_str(jws_t * jws, const char * str_header) { int ret; json_t * j_header = json_loads(str_header, JSON_DECODE_ANY, NULL); ret = r_jws_set_full_header_json_t(jws, j_header); json_decref(j_header); return ret; } int r_jws_set_properties(jws_t * jws, ...) { rhn_opt option; unsigned int ui_value; int ret = RHN_OK; int i_value; rhn_int_t r_value; const char * str_key, * str_value; json_t * j_value; const unsigned char * ustr_value; size_t size_value; jwk_t * jwk; jwks_t * jwks; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; va_list vl; if (jws != NULL) { va_start(vl, jws); for (option = va_arg(vl, rhn_opt); option != RHN_OPT_NONE && ret == RHN_OK; option = va_arg(vl, rhn_opt)) { switch (option) { case RHN_OPT_HEADER_INT_VALUE: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); ret = r_jws_set_header_int_value(jws, str_key, (rhn_int_t)i_value); break; case RHN_OPT_HEADER_RHN_INT_VALUE: str_key = va_arg(vl, const char *); r_value = va_arg(vl, rhn_int_t); ret = r_jws_set_header_int_value(jws, str_key, r_value); break; case RHN_OPT_HEADER_STR_VALUE: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); ret = r_jws_set_header_str_value(jws, str_key, str_value); break; case RHN_OPT_HEADER_JSON_T_VALUE: str_key = va_arg(vl, const char *); j_value = va_arg(vl, json_t *); ret = r_jws_set_header_json_t_value(jws, str_key, j_value); break; case RHN_OPT_HEADER_FULL_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jws_set_full_header_json_t(jws, j_value); break; case RHN_OPT_HEADER_FULL_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jws_set_full_header_json_str(jws, str_value); break; case RHN_OPT_PAYLOAD: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jws_set_payload(jws, ustr_value, size_value); break; case RHN_OPT_SIG_ALG: ui_value = va_arg(vl, unsigned int); ret = r_jws_set_alg(jws, (jwa_alg)ui_value); break; case RHN_OPT_VERIFY_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jws_add_keys(jws, NULL, jwk); break; case RHN_OPT_VERIFY_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jws_add_jwks(jws, NULL, jwks); break; case RHN_OPT_VERIFY_KEY_GNUTLS: pubkey = va_arg(vl, gnutls_pubkey_t); ret = r_jws_add_keys_gnutls(jws, NULL, pubkey); break; case RHN_OPT_VERIFY_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jws_add_keys_json_t(jws, NULL, j_value); break; case RHN_OPT_VERIFY_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jws_add_keys_json_str(jws, NULL, str_value); break; case RHN_OPT_VERIFY_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jws_add_keys_pem_der(jws, (int)ui_value, NULL, 0, ustr_value, size_value); break; case RHN_OPT_SIGN_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jws_add_keys(jws, jwk, NULL); break; case RHN_OPT_SIGN_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jws_add_jwks(jws, jwks, NULL); break; case RHN_OPT_SIGN_KEY_GNUTLS: privkey = va_arg(vl, gnutls_privkey_t); ret = r_jws_add_keys_gnutls(jws, privkey, NULL); break; case RHN_OPT_SIGN_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jws_add_keys_json_t(jws, j_value, NULL); break; case RHN_OPT_SIGN_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jws_add_keys_json_str(jws, str_value, NULL); break; case RHN_OPT_SIGN_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jws_add_keys_pem_der(jws, (int)ui_value, ustr_value, size_value, NULL, 0); break; default: ret = RHN_ERROR_PARAM; break; } } va_end(vl); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jws_set_properties - Error input parameter"); ret = RHN_ERROR_PARAM; } return ret; } rhonabwy-1.1.13/src/jwt.c000066400000000000000000002530171452472117100152010ustar00rootroot00000000000000/** * * Rhonabwy JSON Web Token (JWT) library * * jwt.c: functions definitions * * Copyright 2020-2022 Nicolas Mora * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include #include #include #include #include #include #include int r_jwt_init(jwt_t ** jwt) { int ret; if (jwt != NULL) { if ((*jwt = o_malloc(sizeof(jwt_t))) != NULL) { if (((*jwt)->j_header = json_object()) != NULL) { if (((*jwt)->j_claims = json_object()) != NULL) { if (r_jwks_init(&(*jwt)->jwks_privkey_sign) == RHN_OK) { if (r_jwks_init(&(*jwt)->jwks_pubkey_sign) == RHN_OK) { if (r_jwks_init(&(*jwt)->jwks_privkey_enc) == RHN_OK) { if (r_jwks_init(&(*jwt)->jwks_pubkey_enc) == RHN_OK) { (*jwt)->sign_alg = R_JWA_ALG_UNKNOWN; (*jwt)->enc_alg = R_JWA_ALG_UNKNOWN; (*jwt)->enc = R_JWA_ENC_UNKNOWN; (*jwt)->jws = NULL; (*jwt)->jwe = NULL; (*jwt)->type = R_JWT_TYPE_NONE; (*jwt)->parse_flags = R_PARSE_HEADER_ALL; (*jwt)->key = NULL; (*jwt)->key_len = 0; (*jwt)->iv = NULL; (*jwt)->iv_len = 0; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for jwks_pubkey_enc"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for jwks_privkey_enc"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for jwks_pubkey_sign"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for jwks_privkey_sign"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for j_claims"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for j_header"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_init - Error allocating resources for jwt"); ret = RHN_ERROR_MEMORY; } } else { ret = RHN_ERROR_PARAM; } if (ret != RHN_OK && jwt != NULL) { r_jwt_free(*jwt); *jwt = NULL; } return ret; } void r_jwt_free(jwt_t * jwt) { if (jwt != NULL) { r_jwks_free(jwt->jwks_privkey_sign); r_jwks_free(jwt->jwks_pubkey_sign); r_jwks_free(jwt->jwks_privkey_enc); r_jwks_free(jwt->jwks_pubkey_enc); r_jwe_free(jwt->jwe); r_jws_free(jwt->jws); o_free(jwt->key); o_free(jwt->iv); json_decref(jwt->j_header); json_decref(jwt->j_claims); o_free(jwt); } } jwt_t * r_jwt_copy(jwt_t * jwt) { jwt_t * jwt_copy = NULL; if (jwt != NULL) { if (r_jwt_init(&jwt_copy) == RHN_OK) { jwt_copy->sign_alg = jwt->sign_alg; jwt_copy->enc_alg = jwt->enc_alg; jwt_copy->enc = jwt->enc; json_decref(jwt_copy->j_header); if (r_jwt_set_full_claims_json_t(jwt_copy, jwt->j_claims) != RHN_OK || r_jwt_add_enc_jwks(jwt_copy, jwt->jwks_privkey_enc, jwt->jwks_pubkey_enc) != RHN_OK || r_jwt_add_sign_jwks(jwt_copy, jwt->jwks_privkey_sign, jwt->jwks_pubkey_sign) != RHN_OK || (jwt_copy->j_header = json_deep_copy(jwt->j_header)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_copy - Error setting claims or keys or header"); r_jwt_free(jwt_copy); jwt_copy = NULL; } else { jwt_copy->jwe = r_jwe_copy(jwt->jwe); jwt_copy->jws = r_jws_copy(jwt->jws); } } } return jwt_copy; } int r_jwt_set_header_str_value(jwt_t * jwt, const char * key, const char * str_value) { if (jwt != NULL) { return _r_json_set_str_value(jwt->j_header, key, str_value); } else { return RHN_ERROR_PARAM; } } int r_jwt_set_header_int_value(jwt_t * jwt, const char * key, rhn_int_t i_value) { if (jwt != NULL) { return _r_json_set_int_value(jwt->j_header, key, i_value); } else { return RHN_ERROR_PARAM; } } int r_jwt_set_header_json_t_value(jwt_t * jwt, const char * key, json_t * j_value) { if (jwt != NULL) { return _r_json_set_json_t_value(jwt->j_header, key, j_value); } else { return RHN_ERROR_PARAM; } } const char * r_jwt_get_header_str_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_str_value(jwt->j_header, key); } return NULL; } rhn_int_t r_jwt_get_header_int_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_int_value(jwt->j_header, key); } return 0; } json_t * r_jwt_get_header_json_t_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_json_t_value(jwt->j_header, key); } return NULL; } json_t * r_jwt_get_full_header_json_t(jwt_t * jwt) { if (jwt != NULL) { return _r_json_get_full_json_t(jwt->j_header); } return NULL; } char * r_jwt_get_full_header_str(jwt_t * jwt) { char * to_return = NULL; if (jwt != NULL) { to_return = json_dumps(jwt->j_header, JSON_COMPACT); } return to_return; } int r_jwt_set_claim_str_value(jwt_t * jwt, const char * key, const char * str_value) { if (jwt != NULL) { return _r_json_set_str_value(jwt->j_claims, key, str_value); } else { return RHN_ERROR_PARAM; } } int r_jwt_set_claim_int_value(jwt_t * jwt, const char * key, rhn_int_t i_value) { if (jwt != NULL) { return _r_json_set_int_value(jwt->j_claims, key, i_value); } else { return RHN_ERROR_PARAM; } } int r_jwt_set_claim_json_t_value(jwt_t * jwt, const char * key, json_t * j_value) { if (jwt != NULL) { return _r_json_set_json_t_value(jwt->j_claims, key, j_value); } else { return RHN_ERROR_PARAM; } } const char * r_jwt_get_claim_str_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_str_value(jwt->j_claims, key); } return NULL; } rhn_int_t r_jwt_get_claim_int_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_int_value(jwt->j_claims, key); } return 0; } json_t * r_jwt_get_claim_json_t_value(jwt_t * jwt, const char * key) { if (jwt != NULL) { return _r_json_get_json_t_value(jwt->j_claims, key); } return NULL; } json_t * r_jwt_get_full_claims_json_t(jwt_t * jwt) { if (jwt != NULL) { return _r_json_get_full_json_t(jwt->j_claims); } return NULL; } char * r_jwt_get_full_claims_str(jwt_t * jwt) { char * to_return = NULL; if (jwt != NULL) { to_return = json_dumps(jwt->j_claims, JSON_COMPACT); } return to_return; } int r_jwt_set_full_claims_json_t(jwt_t * jwt, json_t * j_claim) { if (jwt != NULL && json_is_object(j_claim)) { json_decref(jwt->j_claims); jwt->j_claims = json_deep_copy(j_claim); return RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_claims_json_t - Error input parameters"); return RHN_ERROR_PARAM; } } int r_jwt_set_full_claims_json_str(jwt_t * jwt, const char * str_claims) { json_t * j_claims; int ret; if (jwt != NULL && !o_strnullempty(str_claims)) { if ((j_claims = json_loads(str_claims, JSON_DECODE_ANY, NULL)) != NULL) { ret = r_jwt_set_full_claims_json_t(jwt, j_claims); json_decref(j_claims); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_claims_json_str - Error parsing JSON string"); ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_append_claims_json_t(jwt_t * jwt, json_t * j_claim) { json_t * j_claim_copy = json_deep_copy(j_claim); int ret; if (jwt != NULL && j_claim_copy != NULL) { if (!json_object_update(jwt->j_claims, j_claim_copy)) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_append_claims_json_t - Error json_object_update"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } json_decref(j_claim_copy); return ret; } int r_jwt_add_sign_keys(jwt_t * jwt, jwk_t * privkey, jwk_t * pubkey) { int ret = RHN_OK; jwa_alg alg; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwks_append_jwk(jwt->jwks_privkey_sign, privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys - Error setting privkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } if (pubkey != NULL) { if (r_jwks_append_jwk(jwt->jwks_pubkey_sign, pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys - Error setting pubkey"); ret = RHN_ERROR; } } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_sign_jwks(jwt_t * jwt, jwks_t * jwks_privkey, jwks_t * jwks_pubkey) { size_t i; int ret, res; jwk_t * jwk; if (jwt != NULL && (jwks_privkey != NULL || jwks_pubkey != NULL)) { ret = RHN_OK; if (jwks_privkey != NULL) { for (i=0; ret==RHN_OK && ijwks_privkey_sign, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_str - Error setting privkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_str - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_str(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_sign, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_str - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_str - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_sign_keys_json_t(jwt_t * jwt, json_t * privkey, json_t * pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_json_t(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_sign, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_t - Error setting privkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_t - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_t(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_sign, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_t - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_json_t - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_sign_keys_pem_der(jwt_t * jwt, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_pem_der(j_privkey, R_X509_TYPE_PRIVKEY, format, privkey, privkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_sign, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_pem_der - Error setting privkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_pem_der - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_pem_der(j_pubkey, R_X509_TYPE_PUBKEY, format, pubkey, pubkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_sign, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_pem_der - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_pem_der - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_sign_keys_gnutls(jwt_t * jwt, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_gnutls_privkey(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_sign, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_gnutls - Error setting privkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_gnutls - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_gnutls_pubkey(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_sign, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_gnutls - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_keys_gnutls - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_sign_key_symmetric(jwt_t * jwt, const unsigned char * key, size_t key_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_key = NULL; if (jwt != NULL && key != NULL && key_len) { if (r_jwk_init(&j_key) == RHN_OK && r_jwk_import_from_symmetric_key(j_key, key, key_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_sign, j_key) != RHN_OK || r_jwks_append_jwk(jwt->jwks_pubkey_sign, j_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_key_symmetric - Error setting key"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_key, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_sign_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_sign_key_symmetric - Error parsing key"); ret = RHN_ERROR; } r_jwk_free(j_key); } else { ret = RHN_ERROR_PARAM; } return ret; } jwks_t * r_jwt_get_sign_jwks_privkey(jwt_t * jwt) { if (jwt != NULL) { return r_jwks_copy(jwt->jwks_privkey_sign); } else { return NULL; } } jwks_t * r_jwt_get_sign_jwks_pubkey(jwt_t * jwt) { if (jwt != NULL) { return r_jwks_copy(jwt->jwks_pubkey_sign); } else { return NULL; } } int r_jwt_add_enc_keys(jwt_t * jwt, jwk_t * privkey, jwk_t * pubkey) { int ret = RHN_OK; jwa_alg alg; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwks_append_jwk(jwt->jwks_privkey_enc, privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys - Error setting privkey"); ret = RHN_ERROR; } } if (pubkey != NULL) { if (r_jwks_append_jwk(jwt->jwks_pubkey_enc, pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys - Error setting pubkey"); ret = RHN_ERROR; } if (jwt->sign_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(pubkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_enc_jwks(jwt_t * jwt, jwks_t * jwks_privkey, jwks_t * jwks_pubkey) { size_t i; int ret, res; jwk_t * jwk; if (jwt != NULL && (jwks_privkey != NULL || jwks_pubkey != NULL)) { ret = RHN_OK; if (jwks_privkey != NULL) { for (i=0; ret==RHN_OK && ijwks_privkey_enc, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_str - Error setting privkey"); ret = RHN_ERROR; } if (jwt->enc_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_str - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_str(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_enc, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_str - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_str - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_enc_keys_json_t(jwt_t * jwt, json_t * privkey, json_t * pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_json_t(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_enc, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_t - Error setting privkey"); ret = RHN_ERROR; } if (jwt->enc_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_t - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_json_t(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_enc, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_t - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_json_t - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_enc_keys_pem_der(jwt_t * jwt, int format, const unsigned char * privkey, size_t privkey_len, const unsigned char * pubkey, size_t pubkey_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_pem_der(j_privkey, R_X509_TYPE_PRIVKEY, format, privkey, privkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_enc, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_pem_der - Error setting privkey"); ret = RHN_ERROR; } if (jwt->enc_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_pem_der - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_pem_der(j_pubkey, R_X509_TYPE_PUBKEY, format, pubkey, pubkey_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_enc, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_pem_der - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_pem_der - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_enc_keys_gnutls(jwt_t * jwt, gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_privkey = NULL, * j_pubkey = NULL; if (jwt != NULL && (privkey != NULL || pubkey != NULL)) { if (privkey != NULL) { if (r_jwk_init(&j_privkey) == RHN_OK && r_jwk_import_from_gnutls_privkey(j_privkey, privkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_enc, j_privkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_gnutls - Error setting privkey"); ret = RHN_ERROR; } if (jwt->enc_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_privkey, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_gnutls - Error parsing privkey"); ret = RHN_ERROR; } r_jwk_free(j_privkey); } if (pubkey != NULL) { if (r_jwk_init(&j_pubkey) == RHN_OK && r_jwk_import_from_gnutls_pubkey(j_pubkey, pubkey) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_pubkey_enc, j_pubkey) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_gnutls - Error setting pubkey"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_keys_gnutls - Error parsing pubkey"); ret = RHN_ERROR; } r_jwk_free(j_pubkey); } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_add_enc_key_symmetric(jwt_t * jwt, const unsigned char * key, size_t key_len) { int ret = RHN_OK; jwa_alg alg; jwk_t * j_key = NULL; if (jwt != NULL && key != NULL && key_len) { if (r_jwk_init(&j_key) == RHN_OK && r_jwk_import_from_symmetric_key(j_key, key, key_len) == RHN_OK) { if (r_jwks_append_jwk(jwt->jwks_privkey_enc, j_key) != RHN_OK || r_jwks_append_jwk(jwt->jwks_pubkey_enc, j_key) != RHN_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_key_symmetric - Error setting key"); ret = RHN_ERROR; } if (jwt->enc_alg == R_JWA_ALG_UNKNOWN && (alg = r_str_to_jwa_alg(r_jwk_get_property_str(j_key, "alg"))) != R_JWA_ALG_NONE) { r_jwt_set_enc_alg(jwt, alg); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_add_enc_key_symmetric - Error parsing key"); ret = RHN_ERROR; } r_jwk_free(j_key); } else { ret = RHN_ERROR_PARAM; } return ret; } jwks_t * r_jwt_get_enc_jwks_privkey(jwt_t * jwt) { if (jwt != NULL) { return r_jwks_copy(jwt->jwks_privkey_enc); } else { return NULL; } } jwks_t * r_jwt_get_enc_jwks_pubkey(jwt_t * jwt) { if (jwt != NULL) { return r_jwks_copy(jwt->jwks_pubkey_enc); } else { return NULL; } } int r_jwt_set_sign_alg(jwt_t * jwt, jwa_alg alg) { int ret; if (jwt != NULL) { jwt->sign_alg = alg; ret = RHN_OK; } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_alg r_jwt_get_sign_alg(jwt_t * jwt) { if (jwt != NULL) { return jwt->sign_alg; } else { return R_JWA_ALG_UNKNOWN; } } int r_jwt_set_enc_alg(jwt_t * jwt, jwa_alg alg) { int ret; if (jwt != NULL) { jwt->enc_alg = alg; ret = RHN_OK; } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_alg r_jwt_get_enc_alg(jwt_t * jwt) { if (jwt != NULL) { return jwt->enc_alg; } else { return R_JWA_ALG_UNKNOWN; } } int r_jwt_set_enc(jwt_t * jwt, jwa_enc enc) { int ret; if (jwt != NULL) { jwt->enc = enc; ret = RHN_OK; } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_set_enc_cypher_key(jwt_t * jwt, const unsigned char * key, size_t key_len) { int ret; if (jwt != NULL) { o_free(jwt->key); if (key != NULL && key_len) { if ((jwt->key = o_malloc(key_len)) != NULL) { memcpy(jwt->key, key, key_len); jwt->key_len = key_len; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_enc_cypher_key - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; } } else { jwt->key = NULL; jwt->key_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwt_get_enc_cypher_key(jwt_t * jwt, size_t * key_len) { if (jwt != NULL) { if (key_len != NULL) { *key_len = jwt->key_len; } return jwt->key; } return NULL; } int r_jwt_generate_enc_cypher_key(jwt_t * jwt) { int ret; if (jwt != NULL && jwt->enc != R_JWA_ENC_UNKNOWN) { jwt->key_len = _r_get_key_size(jwt->enc); o_free(jwt->key); if (!jwt->key_len) { ret = RHN_ERROR_PARAM; } else if ((jwt->key = o_malloc(jwt->key_len)) != NULL) { if (!gnutls_rnd(GNUTLS_RND_KEY, jwt->key, jwt->key_len)) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_generate_enc_cypher_key - Error gnutls_rnd"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_generate_enc_cypher_key - Error allocating resources for key"); ret = RHN_ERROR_MEMORY; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_generate_enc_cypher_key - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_set_enc_iv(jwt_t * jwt, const unsigned char * iv, size_t iv_len) { int ret; if (jwt != NULL) { o_free(jwt->iv); if (iv != NULL && iv_len) { if ((jwt->iv = o_malloc(iv_len)) != NULL) { memcpy(jwt->iv, iv, iv_len); jwt->iv_len = iv_len; ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_enc_iv - Error allocating resources for iv"); ret = RHN_ERROR_MEMORY; } } else { jwt->iv = NULL; jwt->iv_len = 0; ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const unsigned char * r_jwt_get_enc_iv(jwt_t * jwt, size_t * iv_len) { if (jwt != NULL) { if (iv_len != NULL) { *iv_len = jwt->iv_len; } return jwt->iv; } return NULL; } int r_jwt_generate_enc_iv(jwt_t * jwt) { int ret; if (jwt != NULL && jwt->enc != R_JWA_ENC_UNKNOWN) { jwt->iv_len = (unsigned)gnutls_cipher_get_iv_size(_r_get_alg_from_enc(jwt->enc)); o_free(jwt->iv); jwt->iv = NULL; if (jwt->iv_len) { if ((jwt->iv = o_malloc(jwt->iv_len)) != NULL) { if (!gnutls_rnd(GNUTLS_RND_NONCE, jwt->iv, jwt->iv_len)) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_generate_enc_iv - Error gnutls_rnd"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_generate_enc_iv - Error allocating resources for iv"); ret = RHN_ERROR_MEMORY; } } else { ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } jwa_enc r_jwt_get_enc(jwt_t * jwt) { if (jwt != NULL) { return jwt->enc; } else { return R_JWA_ENC_UNKNOWN; } } const char * r_jwt_get_enc_kid(jwt_t * jwt) { return r_jwe_get_kid(jwt->jwe); } const char * r_jwt_get_sig_kid(jwt_t * jwt) { return r_jws_get_kid(jwt->jws); } char * r_jwt_serialize_signed(jwt_t * jwt, jwk_t * privkey, int x5u_flags) { if (r_jwt_get_sign_alg(jwt) == R_JWA_ALG_NONE) { return NULL; } else { return r_jwt_serialize_signed_unsecure(jwt, privkey, x5u_flags); } } char * r_jwt_serialize_signed_unsecure(jwt_t * jwt, jwk_t * privkey, int x5u_flags) { jws_t * jws = NULL; char * token = NULL, * payload = NULL; jwa_alg alg; json_t * j_header, * j_value = NULL; const char * key = NULL; if (jwt != NULL && ((alg = r_jwt_get_sign_alg(jwt)) != R_JWA_ALG_UNKNOWN || (alg = r_str_to_jwa_alg(r_jwk_get_property_str(privkey, "alg"))) != R_JWA_ALG_NONE)) { if (r_jws_init(&jws) == RHN_OK) { if (r_jwt_get_header_str_value(jwt, "typ") == NULL) { r_jwt_set_header_str_value(jwt, "typ", "JWT"); } j_header = r_jwt_get_full_header_json_t(jwt); json_object_foreach(j_header, key, j_value) { r_jws_set_header_json_t_value(jws, key, j_value); } json_decref(j_header); if (r_jws_add_jwks(jws, jwt->jwks_privkey_sign, jwt->jwks_pubkey_sign) == RHN_OK) { if ((payload = json_dumps(jwt->j_claims, JSON_COMPACT)) != NULL) { if (r_jws_set_alg(jws, alg) == RHN_OK && r_jws_set_payload(jws, (const unsigned char *)payload, o_strlen(payload)) == RHN_OK) { token = r_jws_serialize_unsecure(jws, privkey, x5u_flags); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_signed - Error setting jws"); } o_free(payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_signed - Error json_dumps claims"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_signed - Error r_jws_add_jwks"); } r_jws_free(jws); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_signed - Error r_jws_init"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_signed - Error invalid input parameters"); } return token; } char * r_jwt_serialize_encrypted(jwt_t * jwt, jwk_t * pubkey, int x5u_flags) { jwe_t * jwe = NULL; char * token = NULL, * payload = NULL; jwa_alg alg; jwa_enc enc; json_t * j_header, * j_value = NULL; const char * key = NULL; const unsigned char * key_iv; size_t key_iv_len; if (jwt != NULL && ((alg = r_jwt_get_enc_alg(jwt)) != R_JWA_ALG_UNKNOWN || (alg = r_str_to_jwa_alg(r_jwk_get_property_str(pubkey, "alg"))) != R_JWA_ALG_NONE) && (enc = r_jwt_get_enc(jwt)) != R_JWA_ENC_UNKNOWN) { if (r_jwe_init(&jwe) == RHN_OK) { if (r_jwt_get_header_str_value(jwt, "typ") == NULL) { r_jwt_set_header_str_value(jwt, "typ", "JWT"); } j_header = r_jwt_get_full_header_json_t(jwt); json_object_foreach(j_header, key, j_value) { r_jwe_set_header_json_t_value(jwe, key, j_value); } if ((key_iv = r_jwt_get_enc_cypher_key(jwt, &key_iv_len)) != NULL) { r_jwe_set_cypher_key(jwe, key_iv, key_iv_len); } if ((key_iv = r_jwt_get_enc_iv(jwt, &key_iv_len)) != NULL) { r_jwe_set_iv(jwe, key_iv, key_iv_len); } json_decref(j_header); if (r_jwe_add_jwks(jwe, jwt->jwks_privkey_enc, jwt->jwks_pubkey_enc) == RHN_OK) { if ((payload = json_dumps(jwt->j_claims, JSON_COMPACT)) != NULL) { if (r_jwe_set_alg(jwe, alg) == RHN_OK && r_jwe_set_enc(jwe, enc) == RHN_OK && r_jwe_set_payload(jwe, (const unsigned char *)payload, o_strlen(payload)) == RHN_OK) { token = r_jwe_serialize(jwe, pubkey, x5u_flags); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_encrypted - Error setting jwe"); } o_free(payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_encrypted - Error json_dumps claims"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_encrypted - Error r_jwe_add_jwks"); } r_jwe_free(jwe); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_encrypted - Error r_jwe_init"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_encrypted - Error invalid input parameters"); } return token; } char * r_jwt_serialize_nested(jwt_t * jwt, unsigned int type, jwk_t * sign_key, int sign_key_x5u_flags, jwk_t * encrypt_key, int encrypt_key_x5u_flags) { jwe_t * jwe = NULL; jws_t * jws = NULL; char * token = NULL, * token_intermediate = NULL; jwa_alg sign_alg, enc_alg; jwa_enc enc; json_t * j_header, * j_value = NULL; const char * key = NULL; if (jwt != NULL && ((sign_alg = r_jwt_get_sign_alg(jwt)) != R_JWA_ALG_UNKNOWN || (sign_alg = r_str_to_jwa_alg(r_jwk_get_property_str(sign_key, "alg"))) != R_JWA_ALG_NONE) && ((enc_alg = r_jwt_get_enc_alg(jwt)) != R_JWA_ALG_UNKNOWN || (enc_alg = r_str_to_jwa_alg(r_jwk_get_property_str(encrypt_key, "alg"))) != R_JWA_ALG_NONE) && (enc = r_jwt_get_enc(jwt)) != R_JWA_ENC_UNKNOWN && r_jwt_get_sign_alg(jwt) != R_JWA_ALG_NONE) { if (type == R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT) { if ((token_intermediate = r_jwt_serialize_signed(jwt, sign_key, sign_key_x5u_flags)) != NULL) { if (r_jwe_init(&jwe) == RHN_OK) { if (r_jwe_get_header_str_value(jwe, "typ") != NULL) { r_jwe_set_header_str_value(jwe, "typ", "JWT"); } j_header = r_jwt_get_full_header_json_t(jwt); json_object_foreach(j_header, key, j_value) { r_jwe_set_header_json_t_value(jwe, key, j_value); } json_decref(j_header); r_jwe_set_header_str_value(jwe, "cty", "JWT"); if (r_jwe_add_jwks(jwe, jwt->jwks_privkey_enc, jwt->jwks_pubkey_enc) == RHN_OK) { if (r_jwe_set_alg(jwe, enc_alg) == RHN_OK && r_jwe_set_enc(jwe, enc) == RHN_OK && r_jwe_set_payload(jwe, (const unsigned char *)token_intermediate, o_strlen(token_intermediate)) == RHN_OK) { token = r_jwe_serialize(jwe, encrypt_key, encrypt_key_x5u_flags); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error setting jwe"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jwe_add_jwks"); } r_jwe_free(jwe); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jwe_init"); } o_free(token_intermediate); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jwt_serialize_signed"); } } else if (type == R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN) { if ((token_intermediate = r_jwt_serialize_encrypted(jwt, encrypt_key, encrypt_key_x5u_flags)) != NULL) { if (r_jws_init(&jws) == RHN_OK) { if (r_jwt_get_header_str_value(jwt, "typ") == NULL) { r_jwt_set_header_str_value(jwt, "typ", "JWT"); } j_header = r_jwt_get_full_header_json_t(jwt); json_object_foreach(j_header, key, j_value) { r_jws_set_header_json_t_value(jws, key, j_value); } json_decref(j_header); r_jwt_set_header_str_value(jwt, "cty", "JWT"); if (r_jws_add_jwks(jws, jwt->jwks_privkey_sign, jwt->jwks_pubkey_sign) == RHN_OK) { if (r_jws_set_alg(jws, sign_alg) == RHN_OK && r_jws_set_payload(jws, (const unsigned char *)token_intermediate, o_strlen(token_intermediate)) == RHN_OK) { token = r_jws_serialize(jws, sign_key, sign_key_x5u_flags); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error setting jws"); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jws_add_jwks"); } r_jws_free(jws); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jws_init"); } o_free(token_intermediate); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error r_jwt_serialize_encrypted"); } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_serialize_nested - Error input parameters"); } return token; } int r_jwt_parse(jwt_t * jwt, const char * token, int x5u_flags) { return r_jwt_parsen(jwt, token, o_strlen(token), x5u_flags); } int r_jwt_parsen(jwt_t * jwt, const char * token, size_t token_len, int x5u_flags) { return r_jwt_advanced_parsen(jwt, token, token_len, R_PARSE_HEADER_ALL, x5u_flags); } int r_jwt_parsen_unsecure(jwt_t * jwt, const char * token, size_t token_len, int x5u_flags) { return r_jwt_advanced_parsen(jwt, token, token_len, R_PARSE_ALL, x5u_flags); } int r_jwt_parse_unsecure(jwt_t * jwt, const char * token, int x5u_flags) { return r_jwt_parsen_unsecure(jwt, token, o_strlen(token), x5u_flags); } int r_jwt_advanced_parse(jwt_t * jwt, const char * token, uint32_t parse_flags, int x5u_flags) { return r_jwt_advanced_parsen(jwt, token, o_strlen(token), parse_flags, x5u_flags); } int r_jwt_advanced_parsen(jwt_t * jwt, const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags) { size_t payload_len = 0; int ret, res, token_type = R_JWT_TYPE_NONE; const unsigned char * payload = NULL; char * payload_str = NULL; if (jwt != NULL && token != NULL && token_len) { jwt->parse_flags = parse_flags; token_type = r_jwt_token_typen(token, token_len); if (R_JWT_TYPE_SIGN == token_type) { // JWS r_jws_free(jwt->jws); if ((r_jws_init(&jwt->jws)) == RHN_OK) { if ((res = r_jws_advanced_compact_parsen(jwt->jws, token, token_len, parse_flags, x5u_flags)) == RHN_OK) { json_decref(jwt->j_header); jwt->j_header = json_deep_copy(jwt->jws->j_header); json_decref(jwt->j_claims); jwt->j_claims = NULL; jwt->sign_alg = jwt->jws->alg; r_jwt_add_sign_jwks(jwt, jwt->jws->jwks_privkey, jwt->jws->jwks_pubkey); if (0 != o_strcmp("JWT", r_jwt_get_header_str_value(jwt, "cty"))) { jwt->type = R_JWT_TYPE_SIGN; if ((payload = r_jws_get_payload(jwt->jws, &payload_len)) != NULL && payload_len > 0) { payload_str = o_strndup((const char *)payload, payload_len); if ((jwt->j_claims = json_loads(payload_str, JSON_DECODE_ANY, NULL)) != NULL) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error parsing payload as JSON"); ret = RHN_ERROR; } o_free(payload_str); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error getting payload"); ret = RHN_ERROR; } } else { // Nested JWT jwt->type = R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN; if (r_jws_get_alg(jwt->jws) != R_JWA_ALG_NONE) { if ((payload = r_jws_get_payload(jwt->jws, &payload_len)) != NULL && payload_len > 0) { r_jwe_free(jwt->jwe); if (r_jwe_init(&jwt->jwe) == RHN_OK) { if (r_jwe_advanced_compact_parsen(jwt->jwe, (const char *)payload, payload_len, parse_flags, x5u_flags) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jwe_advanced_compact_parsen"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jwe_init"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error getting payload"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_INVALID; } } } else if (res == RHN_ERROR_PARAM || res == RHN_ERROR_INVALID) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jws_advanced_compact_parsen"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jws_init"); ret = RHN_ERROR; } } else if (R_JWT_TYPE_ENCRYPT == token_type) { // JWE r_jwe_free(jwt->jwe); if ((r_jwe_init(&jwt->jwe)) == RHN_OK) { if ((res = r_jwe_advanced_compact_parsen(jwt->jwe, token, token_len, parse_flags, x5u_flags)) == RHN_OK) { json_decref(jwt->j_header); jwt->j_header = json_deep_copy(jwt->jwe->j_header); jwt->enc_alg = jwt->jwe->alg; jwt->enc = jwt->jwe->enc; r_jwt_add_enc_jwks(jwt, jwt->jwe->jwks_privkey, jwt->jwe->jwks_pubkey); ret = RHN_OK; if (0 != o_strcmp("JWT", r_jwt_get_header_str_value(jwt, "cty"))) { jwt->type = R_JWT_TYPE_ENCRYPT; } else { // Nested JWT jwt->type = R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT; } } else if (res == RHN_ERROR_PARAM) { ret = RHN_ERROR_PARAM; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jwe_advanced_compact_parsen"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error r_jwe_init"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error invalid token format"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_parsen - Error invalid input parameters"); ret = RHN_ERROR_PARAM; } return ret; } jwt_t * r_jwt_quick_parse(const char * token, uint32_t parse_flags, int x5u_flags) { return r_jwt_quick_parsen(token, o_strlen(token), parse_flags, x5u_flags); } jwt_t * r_jwt_quick_parsen(const char * token, size_t token_len, uint32_t parse_flags, int x5u_flags) { jwt_t * jwt = NULL; int ret; if (r_jwt_init(&jwt) == RHN_OK) { ret = r_jwt_advanced_parsen(jwt, token, token_len, parse_flags, x5u_flags); if (ret != RHN_OK) { r_jwt_free(jwt); jwt = NULL; } } else { r_jwt_free(jwt); jwt = NULL; } return jwt; } int r_jwt_get_type(jwt_t * jwt) { if (jwt != NULL) { return jwt->type; } else { return R_JWT_TYPE_NONE; } } int r_jwt_verify_signature(jwt_t * jwt, jwk_t * pubkey, int x5u_flags) { size_t jwks_size, i; jwk_t * jwk; if (jwt != NULL && jwt->jws != NULL) { r_jwks_empty(jwt->jws->jwks_privkey); r_jwks_empty(jwt->jws->jwks_pubkey); jwks_size = r_jwks_size(jwt->jwks_privkey_sign); for (i=0; ijwks_privkey_sign, i); r_jws_add_keys(jwt->jws, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_sign); for (i=0; ijwks_pubkey_sign, i); r_jws_add_keys(jwt->jws, NULL, jwk); r_jwk_free(jwk); } return r_jws_verify_signature(jwt->jws, pubkey, x5u_flags); } else { return RHN_ERROR_PARAM; } } int r_jwt_decrypt(jwt_t * jwt, jwk_t * privkey, int x5u_flags) { const unsigned char * payload = NULL; size_t payload_len = 0, jwks_size, i; json_t * j_payload = NULL; int res, ret; jwk_t * jwk; char * str_payload; if (jwt != NULL && jwt->jwe != NULL) { r_jwks_empty(jwt->jwe->jwks_privkey); r_jwks_empty(jwt->jwe->jwks_pubkey); jwks_size = r_jwks_size(jwt->jwks_privkey_enc); for (i=0; ijwks_privkey_enc, i); r_jwe_add_keys(jwt->jwe, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_enc); for (i=0; ijwks_pubkey_enc, i); r_jwe_add_keys(jwt->jwe, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jwe_decrypt(jwt->jwe, privkey, x5u_flags)) == RHN_OK) { if ((payload = r_jwe_get_payload(jwt->jwe, &payload_len)) != NULL && payload_len > 0) { str_payload = o_strndup((const char *)payload, payload_len); if ((j_payload = json_loads(str_payload, JSON_DECODE_ANY, NULL)) != NULL) { if (r_jwt_set_full_claims_json_t(jwt, j_payload) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt - Error r_jwt_set_full_claims_json_t"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } json_decref(j_payload); o_free(str_payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt - Error getting jwe payload"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt - Error r_jwe_decrypt"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_decrypt_verify_signature_nested(jwt_t * jwt, jwk_t * verify_key, int verify_key_x5u_flags, jwk_t * decrypt_key, int decrypt_key_x5u_flags) { const unsigned char * payload = NULL; char * str_payload; size_t payload_len = 0, jwks_size, i; json_t * j_payload = NULL; int res, ret; jwk_t * jwk; if (jwt != NULL && 0 == o_strcmp("JWT", r_jwt_get_header_str_value(jwt, "cty"))) { if (jwt->type == R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN && jwt->jwe != NULL) { jwks_size = r_jwks_size(jwt->jwks_privkey_sign); for (i=0; ijwks_privkey_sign, i); r_jws_add_keys(jwt->jws, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_sign); for (i=0; ijwks_pubkey_sign, i); r_jws_add_keys(jwt->jws, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jws_verify_signature(jwt->jws, verify_key, verify_key_x5u_flags)) == RHN_OK) { jwks_size = r_jwks_size(jwt->jwks_privkey_enc); for (i=0; ijwks_privkey_enc, i); r_jwe_add_keys(jwt->jwe, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_enc); for (i=0; ijwks_pubkey_enc, i); r_jwe_add_keys(jwt->jwe, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jwe_decrypt(jwt->jwe, decrypt_key, decrypt_key_x5u_flags)) == RHN_OK) { if ((payload = r_jwe_get_payload(jwt->jwe, &payload_len)) != NULL && payload_len > 0) { str_payload = o_strndup((const char *)payload, payload_len); if ((j_payload = json_loads(str_payload, JSON_DECODE_ANY, NULL)) != NULL) { ret = r_jwt_set_full_claims_json_t(jwt, j_payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error JWE payload format"); ret = RHN_ERROR; } json_decref(j_payload); o_free(str_payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error getting JWE payload"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jwe_decrypt"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jws_verify_signature"); ret = RHN_ERROR; } } else if (jwt->type == R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT) { jwks_size = r_jwks_size(jwt->jwks_privkey_enc); for (i=0; ijwks_privkey_enc, i); r_jwe_add_keys(jwt->jwe, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_enc); for (i=0; ijwks_pubkey_enc, i); r_jwe_add_keys(jwt->jwe, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jwe_decrypt(jwt->jwe, decrypt_key, decrypt_key_x5u_flags)) == RHN_OK) { if ((payload = r_jwe_get_payload(jwt->jwe, &payload_len)) != NULL && payload_len > 0) { r_jws_free(jwt->jws); if ((r_jws_init(&jwt->jws)) == RHN_OK) { if (r_jws_advanced_compact_parsen(jwt->jws, (const char *)payload, payload_len, jwt->parse_flags, verify_key_x5u_flags) == RHN_OK) { jwks_size = r_jwks_size(jwt->jwks_privkey_sign); for (i=0; ijwks_privkey_sign, i); r_jws_add_keys(jwt->jws, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_sign); for (i=0; ijwks_pubkey_sign, i); r_jws_add_keys(jwt->jws, NULL, jwk); r_jwk_free(jwk); } json_decref(jwt->j_claims); jwt->j_claims = NULL; jwt->sign_alg = jwt->jws->alg; if ((res = r_jws_verify_signature(jwt->jws, verify_key, verify_key_x5u_flags)) == RHN_OK) { if ((payload = r_jws_get_payload(jwt->jws, &payload_len)) != NULL && payload_len > 0) { str_payload = o_strndup((const char *)payload, payload_len); if ((jwt->j_claims = json_loads(str_payload, JSON_DECODE_ANY, NULL)) != NULL) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error parsing payload as JSON"); ret = RHN_ERROR; } o_free(str_payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error getting payload"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jws_verify_signature"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jws_advanced_compact_parsen"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jws_init"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error getting jwe payload"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jwe_decrypt"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error jwt isn't nested type"); ret = RHN_ERROR_PARAM; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error invalid input token"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_decrypt_nested(jwt_t * jwt, jwk_t * decrypt_key, int decrypt_key_x5u_flags) { int ret, res; json_t * j_payload; jwk_t * jwk; size_t jwks_size, payload_len = 0, i; const unsigned char * payload = NULL; char * str_payload; if (jwt != NULL && jwt->jwe != NULL && (jwt->type == R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN || jwt->type == R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT)) { jwks_size = r_jwks_size(jwt->jwks_privkey_enc); for (i=0; ijwks_privkey_enc, i); r_jwe_add_keys(jwt->jwe, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_enc); for (i=0; ijwks_pubkey_enc, i); r_jwe_add_keys(jwt->jwe, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jwe_decrypt(jwt->jwe, decrypt_key, decrypt_key_x5u_flags)) == RHN_OK) { if ((payload = r_jwe_get_payload(jwt->jwe, &payload_len)) != NULL && payload_len > 0) { if (jwt->type == R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT) { r_jws_free(jwt->jws); if ((r_jws_init(&jwt->jws)) == RHN_OK) { if ((res = r_jws_advanced_compact_parsen(jwt->jws, (const char *)payload, payload_len, jwt->parse_flags, decrypt_key_x5u_flags)) == RHN_OK) { if (r_jwt_add_sign_jwks(jwt, jwt->jws->jwks_privkey, jwt->jws->jwks_pubkey) == RHN_OK) { if (r_jwt_set_sign_alg(jwt, r_jws_get_alg(jwt->jws)) == RHN_OK) { if ((payload = r_jws_get_payload(jwt->jws, &payload_len)) != NULL && payload_len > 0) { str_payload = o_strndup((const char *)payload, payload_len); if ((j_payload = json_loads(str_payload, JSON_DECODE_ANY, NULL)) != NULL) { if (r_jwt_set_full_claims_json_t(jwt, j_payload) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jwt_set_full_claims_json_t"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error loading payload"); ret = RHN_ERROR_PARAM; } json_decref(j_payload); o_free(str_payload); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error getting jws payload"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jwt_set_sign_alg"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jwt_add_sign_jwks"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jws_advanced_compact_parsen"); ret = res; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_verify_signature_nested - Error r_jws_init"); ret = RHN_ERROR; } } else { str_payload = o_strndup((const char *)payload, payload_len); if ((j_payload = json_loads((const char *)str_payload, JSON_DECODE_ANY, NULL)) != NULL) { if (r_jwt_set_full_claims_json_t(jwt, j_payload) == RHN_OK) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jwt_set_full_claims_json_t"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error loading payload"); ret = RHN_ERROR_PARAM; } json_decref(j_payload); o_free(str_payload); } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error getting jwe payload"); ret = RHN_ERROR; } } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error r_jwe_decrypt"); ret = RHN_ERROR; } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_decrypt_nested - Error jwt isn't nested type"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_verify_signature_nested(jwt_t * jwt, jwk_t * verify_key, int verify_key_x5u_flags) { int ret, res; jwk_t * jwk; size_t jwks_size, i; if (jwt != NULL && jwt->jws != NULL && (jwt->type == R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT || jwt->type == R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN)) { jwks_size = r_jwks_size(jwt->jwks_privkey_sign); for (i=0; ijwks_privkey_sign, i); r_jws_add_keys(jwt->jws, jwk, NULL); r_jwk_free(jwk); } jwks_size = r_jwks_size(jwt->jwks_pubkey_sign); for (i=0; ijwks_pubkey_sign, i); r_jws_add_keys(jwt->jws, NULL, jwk); r_jwk_free(jwk); } if ((res = r_jws_verify_signature(jwt->jws, verify_key, verify_key_x5u_flags)) == RHN_OK) { ret = RHN_OK; } else if (res == RHN_ERROR_INVALID || res == RHN_ERROR_PARAM || res == RHN_ERROR_UNSUPPORTED) { ret = res; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_verify_signature_nested - Error r_jws_verify_signature %d", res); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_validate_claims(jwt_t * jwt, ...) { rhn_claim_opt option; int ret = RHN_OK; int i_value, has_invalid_value, has_claim; const char * str_key, * str_value; json_t * j_value, * j_expected_value, * j_element = NULL; va_list vl; time_t now, t_value; size_t index = 0; if (jwt != NULL) { time(&now); va_start(vl, jwt); for (option = va_arg(vl, rhn_claim_opt); option != R_JWT_CLAIM_NOP && ret == RHN_OK; option = va_arg(vl, rhn_claim_opt)) { switch (option) { case R_JWT_CLAIM_ISS: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if (0 != o_strcmp(str_value, r_jwt_get_claim_str_value(jwt, "iss"))) { ret = RHN_ERROR_PARAM; } } else { if (o_strnullempty(r_jwt_get_claim_str_value(jwt, "iss"))) { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_SUB: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if (0 != o_strcmp(str_value, r_jwt_get_claim_str_value(jwt, "sub"))) { ret = RHN_ERROR_PARAM; } } else { if (o_strnullempty(r_jwt_get_claim_str_value(jwt, "sub"))) { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_AUD: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if ((j_value = r_jwt_get_claim_json_t_value(jwt, "aud")) != NULL) { if (json_is_string(j_value)) { if (0 != o_strcmp(str_value, json_string_value(j_value))) { ret = RHN_ERROR_PARAM; } } else if (json_is_array(j_value)) { has_invalid_value = 0; has_claim = 0; json_array_foreach(j_value, index, j_element) { if (!json_is_string(j_element) || !json_string_length(j_element)) { has_invalid_value = 1; } else if (0 == o_strcmp(str_value, json_string_value(j_element))) { has_claim = 1; } } if (!has_claim || has_invalid_value) { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } json_decref(j_value); j_value = NULL; } else { ret = RHN_ERROR_PARAM; } } else { if ((j_value = r_jwt_get_claim_json_t_value(jwt, "aud")) != NULL) { if (json_is_array(j_value)) { has_invalid_value = 0; json_array_foreach(j_value, index, j_element) { if (!json_is_string(j_element) || !json_string_length(j_element)) { has_invalid_value = 1; } } if (has_invalid_value) { ret = RHN_ERROR_PARAM; } } else if (!json_is_string(j_value) || !json_string_length(j_value)) { ret = RHN_ERROR_PARAM; } json_decref(j_value); j_value = NULL; } else { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_JTI: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if (0 != o_strcmp(str_value, r_jwt_get_claim_str_value(jwt, "jti"))) { ret = RHN_ERROR_PARAM; } } else { if (o_strnullempty(r_jwt_get_claim_str_value(jwt, "jti"))) { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_EXP: i_value = va_arg(vl, int); if (i_value == R_JWT_CLAIM_PRESENT && !json_is_integer(json_object_get(jwt->j_claims, "exp"))) { ret = RHN_ERROR_PARAM; } else if (json_is_integer(json_object_get(jwt->j_claims, "exp")) && json_integer_value(json_object_get(jwt->j_claims, "exp")) > 0) { t_value = (time_t)r_jwt_get_claim_int_value(jwt, "exp"); if (i_value == R_JWT_CLAIM_NOW) { if (t_value < now) { ret = RHN_ERROR_PARAM; } } else if (i_value > 0) { if (t_value < (time_t)i_value) { ret = RHN_ERROR_PARAM; } } } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_NBF: i_value = va_arg(vl, int); if (i_value == R_JWT_CLAIM_PRESENT && !json_is_integer(json_object_get(jwt->j_claims, "nbf"))) { ret = RHN_ERROR_PARAM; } else if (json_is_integer(json_object_get(jwt->j_claims, "nbf")) && json_integer_value(json_object_get(jwt->j_claims, "nbf")) > 0) { t_value = (time_t)r_jwt_get_claim_int_value(jwt, "nbf"); if (i_value == R_JWT_CLAIM_NOW) { if (t_value > now) { ret = RHN_ERROR_PARAM; } } else if (i_value > 0) { if (t_value > (time_t)i_value) { ret = RHN_ERROR_PARAM; } } } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_IAT: i_value = va_arg(vl, int); if (i_value == R_JWT_CLAIM_PRESENT && !json_is_integer(json_object_get(jwt->j_claims, "iat"))) { ret = RHN_ERROR_PARAM; } else if (json_is_integer(json_object_get(jwt->j_claims, "iat")) && json_integer_value(json_object_get(jwt->j_claims, "iat")) > 0) { t_value = (time_t)r_jwt_get_claim_int_value(jwt, "iat"); if (i_value == R_JWT_CLAIM_NOW) { if (t_value > now) { ret = RHN_ERROR_PARAM; } } else if (i_value > 0) { if (t_value > (time_t)i_value) { ret = RHN_ERROR_PARAM; } } } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_STR: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); if (str_value == NULL && r_jwt_get_claim_str_value(jwt, str_key) == NULL) { ret = RHN_ERROR_PARAM; } else if (str_value != NULL && 0 != o_strcmp(str_value, r_jwt_get_claim_str_value(jwt, str_key))) { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_INT: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); if (r_jwt_get_claim_int_value(jwt, str_key) != i_value) { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_JSN: str_key = va_arg(vl, const char *); j_expected_value = va_arg(vl, json_t *); j_value = r_jwt_get_claim_json_t_value(jwt, str_key); if (j_value == NULL && j_expected_value == NULL) { ret = RHN_ERROR_PARAM; } else if (j_expected_value != NULL && !json_equal(j_expected_value, j_value)) { ret = RHN_ERROR_PARAM; } json_decref(j_expected_value); break; case R_JWT_CLAIM_TYP: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if (0 != o_strcmp(str_value, r_jwt_get_header_str_value(jwt, "typ"))) { ret = RHN_ERROR_PARAM; } } else { if (o_strnullempty(r_jwt_get_header_str_value(jwt, "typ"))) { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_CTY: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if (0 != o_strcmp(str_value, r_jwt_get_header_str_value(jwt, "cty"))) { ret = RHN_ERROR_PARAM; } } else { if (o_strnullempty(r_jwt_get_header_str_value(jwt, "cty"))) { ret = RHN_ERROR_PARAM; } } break; case R_JWT_CLAIM_AMR: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if ((j_value = r_jwt_get_claim_json_t_value(jwt, "amr")) != NULL) { if (json_is_array(j_value)) { has_invalid_value = 0; has_claim = 0; json_array_foreach(j_value, index, j_element) { if (!json_is_string(j_element) || !json_string_length(j_element)) { has_invalid_value = 1; } else if (0 == o_strcmp(str_value, json_string_value(j_element))) { has_claim = 1; } } if (!has_claim || has_invalid_value) { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } json_decref(j_value); j_value = NULL; } else { ret = RHN_ERROR_PARAM; } } else { if ((j_value = r_jwt_get_claim_json_t_value(jwt, "amr")) != NULL) { if (json_is_array(j_value)) { has_invalid_value = 0; json_array_foreach(j_value, index, j_element) { if (!json_is_string(j_element) || !json_string_length(j_element)) { has_invalid_value = 1; } } if (has_invalid_value) { ret = RHN_ERROR_PARAM; } } else { ret = RHN_ERROR_PARAM; } json_decref(j_value); j_value = NULL; } else { ret = RHN_ERROR_PARAM; } } break; default: ret = RHN_ERROR_PARAM; break; } } va_end(vl); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_set_claims(jwt_t * jwt, ...) { rhn_claim_opt option; int ret = RHN_OK; int i_value; const char * str_key, * str_value; json_t * j_value; va_list vl; time_t now, t_value; if (jwt != NULL) { time(&now); va_start(vl, jwt); for (option = va_arg(vl, rhn_claim_opt); option != R_JWT_CLAIM_NOP && ret == RHN_OK; option = va_arg(vl, rhn_claim_opt)) { switch (option) { case R_JWT_CLAIM_ISS: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_claim_str_value(jwt, "iss", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_SUB: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_claim_str_value(jwt, "sub", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_AUD: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_claim_str_value(jwt, "aud", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_JTI: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_claim_str_value(jwt, "jti", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_EXP: t_value = va_arg(vl, time_t); ret = r_jwt_set_claim_int_value(jwt, "exp", t_value); break; case R_JWT_CLAIM_NBF: i_value = va_arg(vl, int); if (i_value == R_JWT_CLAIM_NOW) { ret = r_jwt_set_claim_int_value(jwt, "nbf", time(NULL)); } else if (i_value >= 0) { ret = r_jwt_set_claim_int_value(jwt, "nbf", i_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_IAT: i_value = va_arg(vl, int); if (i_value == R_JWT_CLAIM_NOW) { ret = r_jwt_set_claim_int_value(jwt, "iat", time(NULL)); } else if (i_value >= 0) { ret = r_jwt_set_claim_int_value(jwt, "iat", i_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_STR: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); if (!o_strnullempty(str_key) && !o_strnullempty(str_value)) { ret = r_jwt_set_claim_str_value(jwt, str_key, str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_INT: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); if (!o_strnullempty(str_key)) { ret = r_jwt_set_claim_int_value(jwt, str_key, i_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_JSN: str_key = va_arg(vl, const char *); j_value = va_arg(vl, json_t *); if (!o_strnullempty(str_key) && j_value != NULL) { ret = r_jwt_set_claim_json_t_value(jwt, str_key, j_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_TYP: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_header_str_value(jwt, "typ", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_CTY: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { ret = r_jwt_set_header_str_value(jwt, "cty", str_value); } else { ret = RHN_ERROR_PARAM; } break; case R_JWT_CLAIM_AMR: str_value = va_arg(vl, const char *); if (!o_strnullempty(str_value)) { if ((j_value = r_jwt_get_claim_json_t_value(jwt, "amr")) == NULL) { j_value = json_pack("[s]", str_value); ret = r_jwt_set_claim_json_t_value(jwt, "amr", j_value); } else { if (json_is_array(j_value)) { json_array_append_new(j_value, json_string(str_value)); ret = r_jwt_set_claim_json_t_value(jwt, "amr", j_value); } else { ret = RHN_ERROR_PARAM; } } json_decref(j_value); j_value = NULL; } else { ret = RHN_ERROR_PARAM; } break; default: ret = RHN_ERROR_PARAM; break; } } va_end(vl); } else { ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_set_full_header_json_t(jwt_t * jwt, json_t * j_header) { int ret = RHN_OK; jwa_alg sign_alg, enc_alg; jwa_enc enc; if (jwt != NULL && json_is_object(j_header)) { if (json_object_get(j_header, "alg") != NULL) { if ((sign_alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg")))) != R_JWA_ALG_UNKNOWN) { jwt->sign_alg = sign_alg; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_header_json_t - Error invalid alg parameter"); ret = RHN_ERROR_PARAM; } } if (json_object_get(j_header, "enc") != NULL) { if ((enc = r_str_to_jwa_enc(json_string_value(json_object_get(j_header, "enc")))) != R_JWA_ENC_UNKNOWN) { jwt->enc = enc; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_header_json_t - Error invalid enc parameter"); ret = RHN_ERROR_PARAM; } if (json_object_get(j_header, "alg") != NULL) { if ((enc_alg = r_str_to_jwa_alg(json_string_value(json_object_get(j_header, "alg")))) != R_JWA_ALG_UNKNOWN) { jwt->enc_alg = enc_alg; } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_header_json_t - Error invalid alg parameter"); ret = RHN_ERROR_PARAM; } } } if (ret == RHN_OK) { json_decref(jwt->j_header); if ((jwt->j_header = json_deep_copy(j_header)) == NULL) { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_header_json_t - Error setting header"); ret = RHN_ERROR_MEMORY; } } } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_full_header_json_t - Error input parameters"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_set_full_header_json_str(jwt_t * jwt, const char * str_header) { int ret; json_t * j_header = json_loads(str_header, JSON_DECODE_ANY, NULL); ret = r_jwt_set_full_header_json_t(jwt, j_header); json_decref(j_header); return ret; } int r_jwt_set_properties(jwt_t * jwt, ...) { rhn_opt option; unsigned int ui_value; int ret = RHN_OK; int i_value; rhn_int_t r_value; const char * str_key, * str_value; json_t * j_value; const unsigned char * ustr_value; size_t size_value; jwk_t * jwk; jwks_t * jwks; gnutls_privkey_t privkey; gnutls_pubkey_t pubkey; va_list vl; if (jwt != NULL) { va_start(vl, jwt); for (option = va_arg(vl, rhn_opt); option != RHN_OPT_NONE && ret == RHN_OK; option = va_arg(vl, rhn_opt)) { switch (option) { case RHN_OPT_HEADER_INT_VALUE: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); ret = r_jwt_set_header_int_value(jwt, str_key, (rhn_int_t)i_value); break; case RHN_OPT_HEADER_RHN_INT_VALUE: str_key = va_arg(vl, const char *); r_value = va_arg(vl, rhn_int_t); ret = r_jwt_set_header_int_value(jwt, str_key, r_value); break; case RHN_OPT_HEADER_STR_VALUE: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); ret = r_jwt_set_header_str_value(jwt, str_key, str_value); break; case RHN_OPT_HEADER_JSON_T_VALUE: str_key = va_arg(vl, const char *); j_value = va_arg(vl, json_t *); ret = r_jwt_set_header_json_t_value(jwt, str_key, j_value); break; case RHN_OPT_HEADER_FULL_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_set_full_header_json_t(jwt, j_value); break; case RHN_OPT_HEADER_FULL_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_set_full_header_json_str(jwt, str_value); break; case RHN_OPT_CLAIM_INT_VALUE: str_key = va_arg(vl, const char *); i_value = va_arg(vl, int); ret = r_jwt_set_claim_int_value(jwt, str_key, (rhn_int_t)i_value); break; case RHN_OPT_CLAIM_RHN_INT_VALUE: str_key = va_arg(vl, const char *); r_value = va_arg(vl, rhn_int_t); ret = r_jwt_set_claim_int_value(jwt, str_key, r_value); break; case RHN_OPT_CLAIM_STR_VALUE: str_key = va_arg(vl, const char *); str_value = va_arg(vl, const char *); ret = r_jwt_set_claim_str_value(jwt, str_key, str_value); break; case RHN_OPT_CLAIM_JSON_T_VALUE: str_key = va_arg(vl, const char *); j_value = va_arg(vl, json_t *); ret = r_jwt_set_claim_json_t_value(jwt, str_key, j_value); break; case RHN_OPT_CLAIM_FULL_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_set_full_claims_json_t(jwt, j_value); break; case RHN_OPT_CLAIM_FULL_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_set_full_claims_json_str(jwt, str_value); break; case RHN_OPT_ENC_ALG: ui_value = va_arg(vl, unsigned int); ret = r_jwt_set_enc_alg(jwt, (jwa_alg)ui_value); break; case RHN_OPT_ENC: ui_value = va_arg(vl, unsigned int); ret = r_jwt_set_enc(jwt, (jwa_enc)ui_value); break; case RHN_OPT_SIG_ALG: ui_value = va_arg(vl, unsigned int); ret = r_jwt_set_sign_alg(jwt, (jwa_alg)ui_value); break; case RHN_OPT_CIPHER_KEY: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_set_enc_cypher_key(jwt, ustr_value, size_value); break; case RHN_OPT_IV: ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_set_enc_iv(jwt, ustr_value, size_value); break; case RHN_OPT_ENCRYPT_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwt_add_enc_keys(jwt, NULL, jwk); break; case RHN_OPT_ENCRYPT_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwt_add_enc_jwks(jwt, NULL, jwks); break; case RHN_OPT_ENCRYPT_KEY_GNUTLS: pubkey = va_arg(vl, gnutls_pubkey_t); ret = r_jwt_add_enc_keys_gnutls(jwt, NULL, pubkey); break; case RHN_OPT_ENCRYPT_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_add_enc_keys_json_t(jwt, NULL, j_value); break; case RHN_OPT_ENCRYPT_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_add_enc_keys_json_str(jwt, NULL, str_value); break; case RHN_OPT_ENCRYPT_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_add_enc_keys_pem_der(jwt, (int)ui_value, NULL, 0, ustr_value, size_value); break; case RHN_OPT_DECRYPT_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwt_add_enc_keys(jwt, jwk, NULL); break; case RHN_OPT_DECRYPT_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwt_add_enc_jwks(jwt, jwks, NULL); break; case RHN_OPT_DECRYPT_KEY_GNUTLS: privkey = va_arg(vl, gnutls_privkey_t); ret = r_jwt_add_enc_keys_gnutls(jwt, privkey, NULL); break; case RHN_OPT_DECRYPT_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_add_enc_keys_json_t(jwt, j_value, NULL); break; case RHN_OPT_DECRYPT_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_add_enc_keys_json_str(jwt, str_value, NULL); break; case RHN_OPT_DECRYPT_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_add_enc_keys_pem_der(jwt, (int)ui_value, ustr_value, size_value, NULL, 0); break; case RHN_OPT_VERIFY_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwt_add_sign_keys(jwt, NULL, jwk); break; case RHN_OPT_VERIFY_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwt_add_sign_jwks(jwt, NULL, jwks); break; case RHN_OPT_VERIFY_KEY_GNUTLS: pubkey = va_arg(vl, gnutls_pubkey_t); ret = r_jwt_add_sign_keys_gnutls(jwt, NULL, pubkey); break; case RHN_OPT_VERIFY_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_add_sign_keys_json_t(jwt, NULL, j_value); break; case RHN_OPT_VERIFY_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_add_sign_keys_json_str(jwt, NULL, str_value); break; case RHN_OPT_VERIFY_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_add_sign_keys_pem_der(jwt, (int)ui_value, NULL, 0, ustr_value, size_value); break; case RHN_OPT_SIGN_KEY_JWK: jwk = va_arg(vl, jwk_t *); ret = r_jwt_add_sign_keys(jwt, jwk, NULL); break; case RHN_OPT_SIGN_KEY_JWKS: jwks = va_arg(vl, jwks_t *); ret = r_jwt_add_sign_jwks(jwt, jwks, NULL); break; case RHN_OPT_SIGN_KEY_GNUTLS: privkey = va_arg(vl, gnutls_privkey_t); ret = r_jwt_add_sign_keys_gnutls(jwt, privkey, NULL); break; case RHN_OPT_SIGN_KEY_JSON_T: j_value = va_arg(vl, json_t *); ret = r_jwt_add_sign_keys_json_t(jwt, j_value, NULL); break; case RHN_OPT_SIGN_KEY_JSON_STR: str_value = va_arg(vl, const char *); ret = r_jwt_add_sign_keys_json_str(jwt, str_value, NULL); break; case RHN_OPT_SIGN_KEY_PEM_DER: ui_value = va_arg(vl, unsigned int); ustr_value = va_arg(vl, const unsigned char *); size_value = va_arg(vl, size_t); ret = r_jwt_add_sign_keys_pem_der(jwt, (int)ui_value, ustr_value, size_value, NULL, 0); break; default: ret = RHN_ERROR_PARAM; break; } } va_end(vl); } else { y_log_message(Y_LOG_LEVEL_ERROR, "r_jwt_set_properties - Error input parameter"); ret = RHN_ERROR_PARAM; } return ret; } int r_jwt_token_type(const char * token) { return r_jwt_token_typen(token, o_strlen(token)); } int r_jwt_token_typen(const char * token, size_t token_len) { size_t nb_dots = 0, i; int ret = R_JWT_TYPE_NONE; if (token != NULL && token_len) { for (i=0; i * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this library. If not, see . * */ #include #include #include #include #define _R_BLOCK_SIZE 256 #ifdef R_WITH_CURL #include #include #define _R_HEADER_CONTENT_TYPE "Content-Type" #endif int r_global_init(void) { o_malloc_t malloc_fn; o_realloc_t realloc_fn; o_free_t free_fn; int ret = RHN_OK; o_get_alloc_funcs(&malloc_fn, &realloc_fn, &free_fn); json_set_alloc_funcs((json_malloc_t)malloc_fn, (json_free_t)free_fn); #ifdef R_WITH_CURL if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_global_init - Error curl_global_init"); ret = RHN_ERROR; } else { if (curl_global_init_mem(CURL_GLOBAL_DEFAULT, malloc_fn, free_fn, realloc_fn, *o_strdup, *calloc) != CURLE_OK) { y_log_message(Y_LOG_LEVEL_ERROR, "r_global_init - Error curl_global_init_mem"); ret = RHN_ERROR_MEMORY; } } #endif return ret; } void r_global_close(void) { #ifdef R_WITH_CURL curl_global_cleanup(); #endif } #ifdef R_WITH_CURL struct _r_response_str { struct _o_datum * datum; size_t size_limit; }; struct _r_expected_content_type { const char * expected; int found; }; static size_t write_response(char *ptr, size_t size, size_t nmemb, void * userdata) { struct _r_response_str * resp = (struct _r_response_str *)userdata; size_t len = (size*nmemb); if (resp->datum->size + len <= resp->size_limit) { if ((resp->datum->data = o_realloc(resp->datum->data, (resp->datum->size + len + 1))) != NULL) { memcpy(resp->datum->data+resp->datum->size, ptr, len); resp->datum->size += len; resp->datum->data[resp->datum->size] = '\0'; return len; } else { resp->datum->size = 0; return 0; } } else { o_free(resp->datum->data); resp->datum->data = NULL; resp->datum->size = resp->size_limit+1; return 0; } } static size_t write_header(void * buffer, size_t size, size_t nitems, void * user_data) { const char * header = (const char *)buffer; struct _r_expected_content_type * expected_content_type = (struct _r_expected_content_type *)user_data; if (o_strncasecmp(header, _R_HEADER_CONTENT_TYPE, o_strlen(_R_HEADER_CONTENT_TYPE)) == 0 && o_strstr(header+o_strlen(_R_HEADER_CONTENT_TYPE)+1, expected_content_type->expected)) { expected_content_type->found = 1; } return nitems * size; } #endif int _r_get_http_content(const char * url, int x5u_flags, const char * expected_content_type, struct _o_datum * datum) { int ret = RHN_OK; #ifdef R_WITH_CURL CURL *curl; struct curl_slist *list = NULL; struct _r_response_str resp; struct _r_expected_content_type ct; long status = 0; int res; curl = curl_easy_init(); if(curl != NULL) { resp.datum = datum; resp.size_limit = R_MAX_BODY_SIZE; // Arbitrary limit response body to 4MB ct.expected = expected_content_type; ct.found = 0; do { if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resp) != CURLE_OK) { ret = RHN_ERROR; break; } if ((list = curl_slist_append(list, "User-Agent: Rhonabwy/" RHONABWY_VERSION_STR)) == NULL) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L) != CURLE_OK) { ret = RHN_ERROR; break; } #if CURL_AT_LEAST_VERSION(7,85,0) if (curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https") != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https") != CURLE_OK) { ret = RHN_ERROR; break; } #else if (curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS) != CURLE_OK) { ret = RHN_ERROR; break; } #endif if (x5u_flags & R_FLAG_FOLLOW_REDIRECT) { if (curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) != CURLE_OK) { ret = RHN_ERROR; break; } } if (x5u_flags & R_FLAG_IGNORE_SERVER_CERTIFICATE) { if (curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0) != CURLE_OK) { ret = RHN_ERROR; break; } } if (!o_strnullempty(expected_content_type)) { if (curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_header) != CURLE_OK) { ret = RHN_ERROR; break; } if (curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &ct) != CURLE_OK) { ret = RHN_ERROR; break; } } if ((res = curl_easy_perform(curl)) != CURLE_OK) { if (res == CURLE_WRITE_ERROR && datum->size > R_MAX_BODY_SIZE) { y_log_message(Y_LOG_LEVEL_ERROR, "_r_get_http_content - Error remote content exceeded size limit of %zu bytes", R_MAX_BODY_SIZE); ret = RHN_ERROR_PARAM; } else { ret = RHN_ERROR; } break; } if (curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &status) != CURLE_OK) { ret = RHN_ERROR; break; } } while (0); curl_easy_cleanup(curl); curl_slist_free_all(list); if (status >= 200 && status < 300) { if (!o_strnullempty(expected_content_type)) { if (!ct.found) { o_free(resp.datum->data); ret = RHN_ERROR; } } } else { o_free(resp.datum->data); ret = RHN_ERROR; } } #else (void)url; (void)x5u_flags; (void)expected_content_type; (void)datum; ret = RHN_ERROR_UNSUPPORTED; #endif return ret; } int _r_json_set_str_value(json_t * j_json, const char * key, const char * str_value) { int ret; if (j_json != NULL && !o_strnullempty(key)) { if (str_value != NULL) { if (!json_object_set_new(j_json, key, json_string(str_value))) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_json_set_str_value - Error json_object_set_new"); ret = RHN_ERROR; } } else { json_object_del(j_json, key); ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } int _r_json_set_int_value(json_t * j_json, const char * key, rhn_int_t i_value) { int ret; if (j_json != NULL && !o_strnullempty(key)) { if (!json_object_set_new(j_json, key, json_integer(i_value))) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_json_set_int_value - Error json_object_set_new"); ret = RHN_ERROR; } } else { ret = RHN_ERROR_PARAM; } return ret; } int _r_json_set_json_t_value(json_t * j_json, const char * key, json_t * j_value) { int ret; if (j_json != NULL && !o_strnullempty(key)) { if (j_value != NULL) { if (!json_object_set_new(j_json, key, json_deep_copy(j_value))) { ret = RHN_OK; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_json_set_json_t_value - Error json_object_set_new"); ret = RHN_ERROR; } } else { json_object_del(j_json, key); ret = RHN_OK; } } else { ret = RHN_ERROR_PARAM; } return ret; } const char * _r_json_get_str_value(json_t * j_json, const char * key) { if (j_json != NULL && !o_strnullempty(key)) { return json_string_value(json_object_get(j_json, key)); } return NULL; } rhn_int_t _r_json_get_int_value(json_t * j_json, const char * key) { if (j_json != NULL && !o_strnullempty(key)) { return json_integer_value(json_object_get(j_json, key)); } return 0; } json_t * _r_json_get_json_t_value(json_t * j_json, const char * key) { json_t * j_value; if (j_json != NULL && !o_strnullempty(key) && (j_value = json_object_get(j_json, key)) != NULL) { return json_deep_copy(j_value); } return NULL; } json_t * _r_json_get_full_json_t(json_t * j_json) { if (j_json != NULL) { return json_deep_copy(j_json); } return NULL; } size_t _r_get_key_size(jwa_enc enc) { size_t size = 0; switch (enc) { case R_JWA_ENC_A128GCM: size = 16; break; case R_JWA_ENC_A192GCM: size = 24; break; case R_JWA_ENC_A128CBC: case R_JWA_ENC_A256GCM: size = 32; break; case R_JWA_ENC_A192CBC: size = 48; break; case R_JWA_ENC_A256CBC: size = 64; break; default: size = 0; break; } return size; } gnutls_cipher_algorithm_t _r_get_alg_from_enc(jwa_enc enc) { gnutls_cipher_algorithm_t alg = GNUTLS_CIPHER_UNKNOWN; switch (enc) { case R_JWA_ENC_A128CBC: alg = GNUTLS_CIPHER_AES_128_CBC; break; case R_JWA_ENC_A192CBC: alg = GNUTLS_CIPHER_AES_192_CBC; break; case R_JWA_ENC_A256CBC: alg = GNUTLS_CIPHER_AES_256_CBC; break; case R_JWA_ENC_A128GCM: alg = GNUTLS_CIPHER_AES_128_GCM; break; case R_JWA_ENC_A192GCM: #if GNUTLS_VERSION_NUMBER >= 0x03060e alg = GNUTLS_CIPHER_AES_192_GCM; #else alg = GNUTLS_CIPHER_UNKNOWN; // Unsupported until GnuTLS 3.6.14 #endif break; case R_JWA_ENC_A256GCM: alg = GNUTLS_CIPHER_AES_256_GCM; break; default: alg = GNUTLS_CIPHER_UNKNOWN; break; } return alg; } int _r_deflate_payload(const unsigned char * uncompressed, size_t uncompressed_len, unsigned char ** compressed, size_t * compressed_len) { int ret = RHN_OK, res; z_stream defstream; *compressed_len = 0; *compressed = NULL; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.avail_in = (uInt)uncompressed_len; defstream.next_in = (Bytef *)uncompressed; if (deflateInit2(&defstream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -9, 8, Z_DEFAULT_STRATEGY) == Z_OK) { do { if ((*compressed = o_realloc(*compressed, (*compressed_len)+_R_BLOCK_SIZE)) != NULL) { defstream.avail_out = _R_BLOCK_SIZE; defstream.next_out = ((Bytef *)*compressed)+(*compressed_len); switch ((res = deflate(&defstream, Z_FINISH))) { case Z_OK: case Z_STREAM_END: case Z_BUF_ERROR: break; default: y_log_message(Y_LOG_LEVEL_ERROR, "_r_deflate_payload - Error deflate %d", res); ret = RHN_ERROR; break; } (*compressed_len) += _R_BLOCK_SIZE - defstream.avail_out; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_deflate_payload - Error allocating resources for *compressed"); ret = RHN_ERROR; } } while (RHN_OK == ret && defstream.avail_out == 0); deflateEnd(&defstream); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_deflate_payload - Error deflateInit"); ret = RHN_ERROR; } return ret; } int _r_inflate_payload(const unsigned char * compressed, size_t compressed_len, unsigned char ** uncompressed, size_t * uncompressed_len) { int ret = RHN_OK, res; z_stream infstream; *uncompressed = NULL; *uncompressed_len = 0; infstream.zalloc = Z_NULL; infstream.zfree = Z_NULL; infstream.opaque = Z_NULL; infstream.avail_in = (uInt)compressed_len; infstream.next_in = (Bytef *)compressed; if (inflateInit2(&infstream, -8) == Z_OK) { do { if (((*uncompressed) = o_realloc((*uncompressed), (*uncompressed_len)+_R_BLOCK_SIZE)) != NULL) { infstream.avail_out = _R_BLOCK_SIZE; infstream.next_out = ((Bytef *)(*uncompressed))+(*uncompressed_len); switch ((res = inflate(&infstream, Z_FINISH))) { case Z_OK: case Z_STREAM_END: case Z_BUF_ERROR: break; default: y_log_message(Y_LOG_LEVEL_ERROR, "_r_inflate_payload - Error inflate %d", res); ret = RHN_ERROR; break; } (*uncompressed_len) += _R_BLOCK_SIZE - infstream.avail_out; } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_inflate_payload - Error allocating resources for data_in_suffix"); ret = RHN_ERROR; } } while (RHN_OK == ret && infstream.avail_out == 0); inflateEnd(&infstream); } else { y_log_message(Y_LOG_LEVEL_ERROR, "_r_inflate_payload - Error inflateInit"); ret = RHN_ERROR; } return ret; } jwa_alg r_str_to_jwa_alg(const char * alg) { if (0 == o_strcmp("none", alg)) { return R_JWA_ALG_NONE; } else if (0 == o_strcmp("HS256", alg)) { return R_JWA_ALG_HS256; } else if (0 == o_strcmp("HS384", alg)) { return R_JWA_ALG_HS384; } else if (0 == o_strcmp("HS512", alg)) { return R_JWA_ALG_HS512; } else if (0 == o_strcmp("RS256", alg)) { return R_JWA_ALG_RS256; } else if (0 == o_strcmp("RS384", alg)) { return R_JWA_ALG_RS384; } else if (0 == o_strcmp("RS512", alg)) { return R_JWA_ALG_RS512; } else if (0 == o_strcmp("ES256", alg)) { return R_JWA_ALG_ES256; } else if (0 == o_strcmp("ES384", alg)) { return R_JWA_ALG_ES384; } else if (0 == o_strcmp("ES512", alg)) { return R_JWA_ALG_ES512; } else if (0 == o_strcmp("EdDSA", alg)) { return R_JWA_ALG_EDDSA; } else if (0 == o_strcmp("ES256K", alg)) { return R_JWA_ALG_ES256K; } else if (0 == o_strcmp("PS256", alg)) { return R_JWA_ALG_PS256; } else if (0 == o_strcmp("PS384", alg)) { return R_JWA_ALG_PS384; } else if (0 == o_strcmp("PS512", alg)) { return R_JWA_ALG_PS512; } else if (0 == o_strcmp("RSA1_5", alg)) { return R_JWA_ALG_RSA1_5; } else if (0 == o_strcmp("RSA-OAEP", alg)) { return R_JWA_ALG_RSA_OAEP; } else if (0 == o_strcmp("RSA-OAEP-256", alg)) { return R_JWA_ALG_RSA_OAEP_256; } else if (0 == o_strcmp("A128KW", alg)) { return R_JWA_ALG_A128KW; } else if (0 == o_strcmp("A192KW", alg)) { return R_JWA_ALG_A192KW; } else if (0 == o_strcmp("A256KW", alg)) { return R_JWA_ALG_A256KW; } else if (0 == o_strcmp("dir", alg)) { return R_JWA_ALG_DIR; } else if (0 == o_strcmp("ECDH-ES", alg)) { return R_JWA_ALG_ECDH_ES; } else if (0 == o_strcmp("ECDH-ES+A128KW", alg)) { return R_JWA_ALG_ECDH_ES_A128KW; } else if (0 == o_strcmp("ECDH-ES+A192KW", alg)) { return R_JWA_ALG_ECDH_ES_A192KW; } else if (0 == o_strcmp("ECDH-ES+A256KW", alg)) { return R_JWA_ALG_ECDH_ES_A256KW; } else if (0 == o_strcmp("A128GCMKW", alg)) { return R_JWA_ALG_A128GCMKW; } else if (0 == o_strcmp("A192GCMKW", alg)) { return R_JWA_ALG_A192GCMKW; } else if (0 == o_strcmp("A256GCMKW", alg)) { return R_JWA_ALG_A256GCMKW; } else if (0 == o_strcmp("PBES2-HS256+A128KW", alg)) { return R_JWA_ALG_PBES2_H256; } else if (0 == o_strcmp("PBES2-HS384+A192KW", alg)) { return R_JWA_ALG_PBES2_H384; } else if (0 == o_strcmp("PBES2-HS512+A256KW", alg)) { return R_JWA_ALG_PBES2_H512; } else if (0 == o_strcmp("ES256K", alg)) { return R_JWA_ALG_ES256K; } else { return R_JWA_ALG_UNKNOWN; } } const char * r_jwa_alg_to_str(jwa_alg alg) { switch (alg) { case R_JWA_ALG_NONE: return "none"; break; case R_JWA_ALG_HS256: return "HS256"; break; case R_JWA_ALG_HS384: return "HS384"; break; case R_JWA_ALG_HS512: return "HS512"; break; case R_JWA_ALG_RS256: return "RS256"; break; case R_JWA_ALG_RS384: return "RS384"; break; case R_JWA_ALG_RS512: return "RS512"; break; case R_JWA_ALG_ES256: return "ES256"; break; case R_JWA_ALG_ES384: return "ES384"; break; case R_JWA_ALG_ES512: return "ES512"; break; case R_JWA_ALG_EDDSA: return "EdDSA"; break; case R_JWA_ALG_ES256K: return "ES256K"; break; case R_JWA_ALG_PS256: return "PS256"; break; case R_JWA_ALG_PS384: return "PS384"; break; case R_JWA_ALG_PS512: return "PS512"; break; case R_JWA_ALG_RSA1_5: return "RSA1_5"; break; case R_JWA_ALG_RSA_OAEP: return "RSA-OAEP"; break; case R_JWA_ALG_RSA_OAEP_256: return "RSA-OAEP-256"; break; case R_JWA_ALG_A128KW: return "A128KW"; break; case R_JWA_ALG_A192KW: return "A192KW"; break; case R_JWA_ALG_A256KW: return "A256KW"; break; case R_JWA_ALG_DIR: return "dir"; break; case R_JWA_ALG_ECDH_ES: return "ECDH-ES"; break; case R_JWA_ALG_ECDH_ES_A128KW: return "ECDH-ES+A128KW"; break; case R_JWA_ALG_ECDH_ES_A192KW: return "ECDH-ES+A192KW"; break; case R_JWA_ALG_ECDH_ES_A256KW: return "ECDH-ES+A256KW"; break; case R_JWA_ALG_A128GCMKW: return "A128GCMKW"; break; case R_JWA_ALG_A192GCMKW: return "A192GCMKW"; break; case R_JWA_ALG_A256GCMKW: return "A256GCMKW"; break; case R_JWA_ALG_PBES2_H256: return "PBES2-HS256+A128KW"; break; case R_JWA_ALG_PBES2_H384: return "PBES2-HS384+A192KW"; break; case R_JWA_ALG_PBES2_H512: return "PBES2-HS512+A256KW"; break; default: return NULL; break; } } jwa_enc r_str_to_jwa_enc(const char * enc) { if (0 == o_strcmp("A128CBC-HS256", enc)) { return R_JWA_ENC_A128CBC; } else if (0 == o_strcmp("A192CBC-HS384", enc)) { return R_JWA_ENC_A192CBC; } else if (0 == o_strcmp("A256CBC-HS512", enc)) { return R_JWA_ENC_A256CBC; } else if (0 == o_strcmp("A128GCM", enc)) { return R_JWA_ENC_A128GCM; } else if (0 == o_strcmp("A192GCM", enc)) { return R_JWA_ENC_A192GCM; } else if (0 == o_strcmp("A256GCM", enc)) { return R_JWA_ENC_A256GCM; } else { return R_JWA_ENC_UNKNOWN; } } const char * r_jwa_enc_to_str(jwa_enc enc) { switch (enc) { case R_JWA_ENC_A128CBC: return "A128CBC-HS256"; break; case R_JWA_ENC_A192CBC: return "A192CBC-HS384"; break; case R_JWA_ENC_A256CBC: return "A256CBC-HS512"; break; case R_JWA_ENC_A128GCM: return "A128GCM"; break; case R_JWA_ENC_A192GCM: return "A192GCM"; break; case R_JWA_ENC_A256GCM: return "A256GCM"; break; default: return NULL; break; } } json_t * r_library_info_json_t(void) { json_t * j_info = json_pack("{sss{s[sssssss]}s{s[ssss]s[sssss]}}", "version", RHONABWY_VERSION_STR, "jws", "alg", "none", "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "jwe", "alg", "RSA1_5", "dir", "A128GCMKW", "A256GCMKW", "enc", "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A256GCM"); #if GNUTLS_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES512")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("EdDSA")); //json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256K")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS512")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060e json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192GCMKW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "enc"), json_string("A192GCM")); #endif #if NETTLE_VERSION_NUMBER >= 0x030400 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP-256")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A256KW")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS256+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS384+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS512+A256KW")); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A256KW")); #endif return j_info; } char * r_library_info_json_str(void) { char * to_return = NULL; json_t * j_info = r_library_info_json_t(); if (j_info != NULL) { to_return = json_dumps(j_info, JSON_COMPACT); } json_decref(j_info); return to_return; } void r_free(void * data) { o_free(data); } rhonabwy-1.1.13/test/000077500000000000000000000000001452472117100144115ustar00rootroot00000000000000rhonabwy-1.1.13/test/.gitignore000066400000000000000000000003761452472117100164070ustar00rootroot00000000000000jwk_core jwk_import jwk_export jwks_core jws_core jws_hmac jws_ecdsa jws_rsa jws_rsapss jws_json jwe_core jwe_rsa jwe_dir jwe_aesgcm jwe_kw jwe_pbes2 jwe_rsa_oaep jwe_ecdh jwe_json jwt_core jwt_sign jwt_encrypt jwt_nested misc cookbook *.log *.crt *.key rhonabwy-1.1.13/test/Makefile000066400000000000000000000047621452472117100160620ustar00rootroot00000000000000# # Rhonabwy library # # Makefile used to build the tests # # Public domain, no copyright. Use at your own risk. # RHONABWY_INCLUDE=../include RHONABWY_LOCATION=../src RHONABWY_LIBRARY=$(RHONABWY_LOCATION)/librhonabwy.so CC=gcc CFLAGS+=-Wall -D_REENTRANT -I$(RHONABWY_INCLUDE) -DDEBUG -g -O0 $(CPPFLAGS) LDFLAGS=-lc -L$(RHONABWY_LIBRARY) -lrhonabwy $(shell pkg-config --libs liborcania) $(shell pkg-config --libs libyder) $(shell pkg-config --libs libulfius) $(shell pkg-config --libs jansson) $(shell pkg-config --libs check) $(shell pkg-config --libs gnutls) $(shell pkg-config --libs check) VALGRIND_COMMAND=valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all TARGET_JWK=jwk_core jwk_import jwk_export jwks_core TARGET_JWS=jws_core jws_hmac jws_rsa jws_ecdsa jws_rsapss jws_json TARGET_JWE=jwe_core jwe_rsa jwe_dir jwe_aesgcm jwe_kw jwe_pbes2 jwe_rsa_oaep jwe_ecdh jwe_json TARGET_JWT=jwt_core jwt_sign jwt_encrypt jwt_nested TARGET=$(TARGET_JWK) $(TARGET_JWS) $(TARGET_JWE) $(TARGET_JWT) misc cookbook VERBOSE=0 MEMCHECK=0 CERT=cert all: test clean: rm -f *.o $(TARGET) *.log valgrind-*.txt $(CERT)/*.crt $(CERT)/*.key $(CERT)/server.key: ./$(CERT)/create-cert.sh $(RHONABWY_LIBRARY): $(RHONABWY_LOCATION)/misc.c $(RHONABWY_LOCATION)/jwk.c $(RHONABWY_LOCATION)/jwks.c $(RHONABWY_LOCATION)/jws.c $(RHONABWY_LOCATION)/jwe.c $(RHONABWY_LOCATION)/jwt.c $(RHONABWY_INCLUDE)/rhonabwy.h cd $(RHONABWY_LOCATION) && $(MAKE) debug $* %: %.c $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) test_%: % $(RHONABWY_LIBRARY) $(CERT)/server.key @if [ "$(VERBOSE)" = "0" ] && [ "$(MEMCHECK)" = "0" ]; then \ LD_LIBRARY_PATH=$(RHONABWY_LOCATION):${LD_LIBRARY_PATH} ./run_test.sh ./$^; \ elif [ "$(MEMCHECK)" = "0" ]; then \ LD_LIBRARY_PATH=$(RHONABWY_LOCATION):${LD_LIBRARY_PATH} ./$^ ; \ else \ CK_FORK=no LD_LIBRARY_PATH=$(RHONABWY_LOCATION):${LD_LIBRARY_PATH} $(VALGRIND_COMMAND) ./$^ 2>valgrind-$@.txt; \ fi test-jwk: $(RHONABWY_LIBRARY) $(TARGET_JWK) test_jwk_core test_jwk_import test_jwk_export test_jwks_core test-jws: $(RHONABWY_LIBRARY) $(TARGET_JWS) test_jws_core test_jws_hmac test_jws_rsa test_jws_ecdsa test_jws_rsapss test_jws_json test-jwe: $(RHONABWY_LIBRARY) $(TARGET_JWE) test_jwe_core test_jwe_rsa test_jwe_dir test_jwe_aesgcm test_jwe_kw test_jwe_pbes2 test_jwe_rsa_oaep test_jwe_ecdh test_jwe_json test-jwt: $(RHONABWY_LIBRARY) $(TARGET_JWT) test_jwt_core test_jwt_sign test_jwt_encrypt test_jwt_nested test: $(RHONABWY_LIBRARY) $(TARGET) test_misc test_cookbook test-jwk test-jws test-jwe test-jwt check: test rhonabwy-1.1.13/test/cert/000077500000000000000000000000001452472117100153465ustar00rootroot00000000000000rhonabwy-1.1.13/test/cert/create-cert.sh000077500000000000000000000073431452472117100201120ustar00rootroot00000000000000#!/bin/sh # # Rhonabwy # # Create certificates # # Public domain, no copyright. Use at your own risk. # DEST=../test/cert RET=0 case "$OSTYPE" in *"darwin"*) # Apple has its own certtool which is incompatible. GnuTLS' certtool is renamed as # gnutls-certtool in MacPorts/homebrew. CERTTOOL=gnutls-certtool;; *) CERTTOOL=certtool;; esac # clean old certs rm -f $DEST/root* $DEST/user* $DEST/fullchain* echo >> $DEST/certtool.log echo Generate Rhonabwy test certificates >> $DEST/certtool.log echo >> $DEST/certtool.log # www cert $CERTTOOL --generate-privkey --outfile $DEST/server.key --sec-param High 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "server.key \033[0;32mOK\033[0m\n" else printf "server.key \033[0;31mError\033[0m\n" RET=$STATUS fi $CERTTOOL --generate-self-signed --load-privkey $DEST/server.key --outfile $DEST/server.crt --template $DEST/template-server.cfg 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "server.crt \033[0;32mOK\033[0m\n" else printf "server.crt \033[0;31mError\033[0m\n" RET=$STATUS fi # CA root $CERTTOOL --generate-privkey --outfile $DEST/root1.key --sec-param High 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "root1.key \033[0;32mOK\033[0m\n" else printf "root1.key \033[0;31mError\033[0m\n" RET=$STATUS fi $CERTTOOL --generate-self-signed --load-privkey $DEST/root1.key --outfile $DEST/root1.crt --template $DEST/template-ca.cfg 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "root1.crt \033[0;32mOK\033[0m\n" else printf "root1.crt \033[0;31mError\033[0m\n" RET=$STATUS fi # user 1 $CERTTOOL --generate-privkey --outfile $DEST/user1.key --sec-param High 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "user1.key \033[0;32mOK\033[0m\n" else printf "user1.key \033[0;31mError\033[0m\n" RET=$STATUS fi $CERTTOOL --generate-certificate --load-privkey $DEST/user1.key --load-ca-certificate $DEST/root1.crt --load-ca-privkey $DEST/root1.key --outfile $DEST/user1.crt --template $DEST/template-user.cfg 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "user1.crt \033[0;32mOK\033[0m\n" else printf "user1.crt \033[0;31mError\033[0m\n" RET=$STATUS fi # CA root 2 $CERTTOOL --generate-privkey --outfile $DEST/root2.key --sec-param High 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "root2.key \033[0;32mOK\033[0m\n" else printf "root2.key \033[0;31mError\033[0m\n" RET=$STATUS fi $CERTTOOL --generate-self-signed --load-privkey $DEST/root2.key --outfile $DEST/root2.crt --template $DEST/template-ca2.cfg 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "root2.crt \033[0;32mOK\033[0m\n" else printf "root2.crt \033[0;31mError\033[0m\n" RET=$STATUS fi # user 2 $CERTTOOL --generate-privkey --outfile $DEST/user2.key --sec-param High 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "user2.key \033[0;32mOK\033[0m\n" else printf "user2.key \033[0;31mError\033[0m\n" RET=$STATUS fi $CERTTOOL --generate-certificate --load-privkey $DEST/user2.key --load-ca-certificate $DEST/root2.crt --load-ca-privkey $DEST/root2.key --outfile $DEST/user2.crt --template $DEST/template-user.cfg 2>>$DEST/certtool.log STATUS=$? if [ $STATUS -eq 0 ]; then printf "user2.crt \033[0;32mOK\033[0m\n" else printf "user2.crt \033[0;31mError\033[0m\n" RET=$STATUS fi # create chain files cat $DEST/user1.crt $DEST/root1.crt > $DEST/fullchain1.crt cat $DEST/user2.crt $DEST/root2.crt > $DEST/fullchain2.crt cat $DEST/user2.crt $DEST/root1.crt > $DEST/fullchain-error.crt rhonabwy-1.1.13/test/cert/template-ca.cfg000066400000000000000000000026421452472117100202270ustar00rootroot00000000000000# X.509 Certificate options # # Source: https://help.ubuntu.com/community/GnuTLS # # DN options # The organization of the subject. organization = "babelouest" # The common name of the certificate owner. cn = "rhonabwy_1" # In how many days, counting from today, this certificate will expire. # Use -1 if there is no expiration date. expiration_days = 700 # Whether this is a CA certificate or not ca # Whether this certificate will be used to sign data (needed # in TLS DHE ciphersuites). This is the digitalSignature flag # in RFC5280 terminology. signing_key # Whether this certificate will be used to encrypt data (needed # in TLS RSA ciphersuites). Note that it is preferred to use different # keys for encryption and signing. This is the keyEncipherment flag # in RFC5280 terminology. encryption_key # Whether this key will be used to sign other certificates. The # keyCertSign flag in RFC5280 terminology. cert_signing_key # Whether this key will be used to sign CRLs. The # cRLSign flag in RFC5280 terminology. #crl_signing_key # The keyAgreement flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #key_agreement # The dataEncipherment flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #data_encipherment # The nonRepudiation flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #non_repudiation rhonabwy-1.1.13/test/cert/template-ca2.cfg000066400000000000000000000026421452472117100203110ustar00rootroot00000000000000# X.509 Certificate options # # Source: https://help.ubuntu.com/community/GnuTLS # # DN options # The organization of the subject. organization = "babelouest" # The common name of the certificate owner. cn = "rhonabwy_2" # In how many days, counting from today, this certificate will expire. # Use -1 if there is no expiration date. expiration_days = 700 # Whether this is a CA certificate or not ca # Whether this certificate will be used to sign data (needed # in TLS DHE ciphersuites). This is the digitalSignature flag # in RFC5280 terminology. signing_key # Whether this certificate will be used to encrypt data (needed # in TLS RSA ciphersuites). Note that it is preferred to use different # keys for encryption and signing. This is the keyEncipherment flag # in RFC5280 terminology. encryption_key # Whether this key will be used to sign other certificates. The # keyCertSign flag in RFC5280 terminology. cert_signing_key # Whether this key will be used to sign CRLs. The # cRLSign flag in RFC5280 terminology. #crl_signing_key # The keyAgreement flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #key_agreement # The dataEncipherment flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #data_encipherment # The nonRepudiation flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #non_repudiation rhonabwy-1.1.13/test/cert/template-server.cfg000066400000000000000000000025661452472117100211570ustar00rootroot00000000000000# X.509 Certificate options # # Source: https://help.ubuntu.com/community/GnuTLS # # DN options # The organization of the subject. organization = "babelouest" # The common name of the certificate owner. cn = "rhonabwy_www" # In how many days, counting from today, this certificate will expire. # Use -1 if there is no expiration date. expiration_days = 700 # Whether this certificate will be used to sign data (needed # in TLS DHE ciphersuites). This is the digitalSignature flag # in RFC5280 terminology. signing_key # Whether this certificate will be used to encrypt data (needed # in TLS RSA ciphersuites). Note that it is preferred to use different # keys for encryption and signing. This is the keyEncipherment flag # in RFC5280 terminology. encryption_key # Whether this key will be used to sign other certificates. The # keyCertSign flag in RFC5280 terminology. cert_signing_key # Whether this key will be used to sign CRLs. The # cRLSign flag in RFC5280 terminology. #crl_signing_key # The keyAgreement flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #key_agreement # The dataEncipherment flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #data_encipherment # The nonRepudiation flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #non_repudiation rhonabwy-1.1.13/test/cert/template-user.cfg000066400000000000000000000052601452472117100206210ustar00rootroot00000000000000# X.509 Certificate options # # Source: https://help.ubuntu.com/community/GnuTLS # # DN options # The organization of the subject. organization = "babelouest" # The common name of the certificate owner. cn = "Dave Lopper" # In how many days, counting from today, this certificate will expire. # Use -1 if there is no expiration date. expiration_days = 350 #### Key usage # The following key usage flags are used by CAs and end certificates # Whether this certificate will be used to sign data (needed # in TLS DHE ciphersuites). This is the digitalSignature flag # in RFC5280 terminology. signing_key # Whether this certificate will be used to encrypt data (needed # in TLS RSA ciphersuites). Note that it is preferred to use different # keys for encryption and signing. This is the keyEncipherment flag # in RFC5280 terminology. encryption_key # Whether this key will be used to sign other certificates. The # keyCertSign flag in RFC5280 terminology. #cert_signing_key # Whether this key will be used to sign CRLs. The # cRLSign flag in RFC5280 terminology. #crl_signing_key # The keyAgreement flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #key_agreement # The dataEncipherment flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #data_encipherment # The nonRepudiation flag of RFC5280. It's purpose is loosely # defined. Not use it unless required by a protocol. #non_repudiation #### Extended key usage (key purposes) # The following extensions are used in an end certificate # to clarify its purpose. Some CAs also use it to indicate # the types of certificates they are purposed to sign. # Whether this certificate will be used for a TLS client; # this sets the id-kp-serverAuth (1.3.6.1.5.5.7.3.1) of # extended key usage. #tls_www_client # Whether this certificate will be used for a TLS server; # This sets the id-kp-clientAuth (1.3.6.1.5.5.7.3.2) of # extended key usage. #tls_www_server # Whether this key will be used to sign code. This sets the # id-kp-codeSigning (1.3.6.1.5.5.7.3.3) of extended key usage # extension. #code_signing_key # Whether this key will be used to sign OCSP data. This sets the # id-kp-OCSPSigning (1.3.6.1.5.5.7.3.9) of extended key usage extension. #ocsp_signing_key # Whether this key will be used for time stamping. This sets the # id-kp-timeStamping (1.3.6.1.5.5.7.3.8) of extended key usage extension. #time_stamping_key # Whether this key will be used for email protection. This sets the # id-kp-emailProtection (1.3.6.1.5.5.7.3.4) of extended key usage extension. #email_protection_key # Whether this key will be used for IPsec IKE operations (1.3.6.1.5.5.7.3.17). #ipsec_ike_key rhonabwy-1.1.13/test/cookbook-master/000077500000000000000000000000001452472117100175105ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/6.nesting_signatures_and_encryption.json000066400000000000000000000324631452472117100275660ustar00rootroot00000000000000{ "title": "Nesting Signatures and Encryption", "sign": { "input": { "payload": "{\"iss\":\"hobbiton.example\",\"exp\":1300819380,\"http://example.com/is_root\":true}", "key": { "kty": "RSA", "kid": "hobbiton.example", "use": "sig", "n": "kNrPIBDXMU6fcyv5i-QHQAQ-K8gsC3HJb7FYhYaw8hXbNJa-t8q0lDKwLZgQXYV-ffWxXJv5GGrlZE4GU52lfMEegTDzYTrRQ3tepgKFjMGg6Iy6fkl1ZNsx2gEonsnlShfzA9GJwRTmtKPbk1s-hwx1IU5AT-AIelNqBgcF2vE5W25_SGGBoaROVdUYxqETDggM1z5cKV4ZjDZ8-lh4oVB07bkac6LQdHpJUUySH_Er20DXx30Kyi97PciXKTS-QKXnmm8ivyRCmux22ZoPUind2BKC5OiG4MwALhaL2Z2k8CsRdfy-7dg7z41Rp6D0ZeEvtaUp4bX4aKraL4rTfw", "e": "AQAB", "d": "ZLe_TIxpE9-W_n2VBa-HWvuYPtjvxwVXClJFOpJsdea8g9RMx34qEOEtnoYc2un3CZ3LtJi-mju5RAT8YSc76YJds3ZVw0UiO8mMBeG6-iOnvgobobNx7K57-xjTJZU72EjOr9kB7z6ZKwDDq7HFyCDhUEcYcHFVc7iL_6TibVhAhOFONWlqlJgEgwVYd0rybNGKifdnpEbwyHoMwY6HM1qvnEFgP7iZ0YzHUT535x6jj4VKcdA7ZduFkhUauysySEW7mxZM6fj1vdjJIy9LD1fIz30Xv4ckoqhKF5GONU6tNmMmNgAD6gIViyEle1PrIxl1tBhCI14bRW-zrpHgAQ", "p": "yKWYoNIAqwMRQlgIBOdT1NIcbDNUUs2Rh-pBaxD_mIkweMt4Mg-0-B2iSYvMrs8horhonV7vxCQagcBAATGW-hAafUehWjxWSH-3KccRM8toL4e0q7M-idRDOBXSoe7Z2-CV2x_ZCY3RP8qp642R13WgXqGDIM4MbUkZSjcY9-c", "q": "uND4o15V30KDzf8vFJw589p1vlQVQ3NEilrinRUPHkkxaAzDzccGgrWMWpGxGFFnNL3w5CqPLeU76-5IVYQq0HwYVl0hVXQHr7sgaGu-483Ad3ENcL23FrOnF45m7_2ooAstJDe49MeLTTQKrSIBl_SKvqpYvfSPTczPcZkh9Kk", "dp": "jmTnEoq2qqa8ouaymjhJSCnsveUXnMQC2gAneQJRQkFqQu-zV2PKPKNbPvKVyiF5b2-L3tM3OW2d2iNDyRUWXlT7V5l0KwPTABSTOnTqAmYChGi8kXXdlhcrtSvXldBakC6saxwI_TzGGY2MVXzc2ZnCvCXHV4qjSxOrfP3pHFU", "dq": "R9FUvU88OVzEkTkXl3-5-WusE4DjHmndeZIlu3rifBdfLpq_P-iWPBbGaq9wzQ1c-J7SzCdJqkEJDv5yd2C7rnZ6kpzwBh_nmL8zscAk1qsunnt9CJGAYz7-sGWy1JGShFazfP52ThB4rlCJ0YuEaQMrIzpY77_oLAhpmDA0hLk", "qi": "S8tC7ZknW6hPITkjcwttQOPLVmRfwirRlFAViuDb8NW9CrV_7F2OqUZCqmzHTYAumwGFHI1WVRep7anleWaJjxC_1b3fq_al4qH3Pe-EKiHg6IMazuRtZLUROcThrExDbF5dYbsciDnfRUWLErZ4N1Be0bnxYuPqxwKd9QZwMo0" }, "alg": "PS256" }, "signing": { "protected": { "alg": "PS256", "typ": "JWT" }, "protected_b64u": "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9", "sig-input": "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJob2JiaXRvbi5leGFtcGxlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZX0", "sig": "dPpMqwRZxFYi1UfcDAaf8M99o7kwUWtiXZ-ByvVuJih4MhJ_aZqciprz0OWaIAkIvn1qskChirjKvY9ESZNUCP4JjvfyPS-nqjJxYoA5ztWOyFk2cZNIPXjcJXSQwXPO9tEe-v4VSqgD0aKHqPxYog4N6Cz1lKph1U1sYDSI67_bLL7elg_vkjfMp5_W5l5LuUYGMeh6hxQIaIUXf9EwV2JmvTMuZ-vBOWy0Sniy1EFo72CRTvmtrIf5AROo5MNliY3KtUxeP-SOmD-LEYwW9SlkohYzMVAZDDOrVbv7KVRHpeYNaK75KEQqdCEEkS_rskZS-Qtt_nlegTWh1mEYaA" }, "output": { "compact": "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJob2JiaXRvbi5leGFtcGxlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZX0.dPpMqwRZxFYi1UfcDAaf8M99o7kwUWtiXZ-ByvVuJih4MhJ_aZqciprz0OWaIAkIvn1qskChirjKvY9ESZNUCP4JjvfyPS-nqjJxYoA5ztWOyFk2cZNIPXjcJXSQwXPO9tEe-v4VSqgD0aKHqPxYog4N6Cz1lKph1U1sYDSI67_bLL7elg_vkjfMp5_W5l5LuUYGMeh6hxQIaIUXf9EwV2JmvTMuZ-vBOWy0Sniy1EFo72CRTvmtrIf5AROo5MNliY3KtUxeP-SOmD-LEYwW9SlkohYzMVAZDDOrVbv7KVRHpeYNaK75KEQqdCEEkS_rskZS-Qtt_nlegTWh1mEYaA" } }, "encrypt": { "input": { "plaintext": "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJob2JiaXRvbi5leGFtcGxlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZX0.dPpMqwRZxFYi1UfcDAaf8M99o7kwUWtiXZ-ByvVuJih4MhJ_aZqciprz0OWaIAkIvn1qskChirjKvY9ESZNUCP4JjvfyPS-nqjJxYoA5ztWOyFk2cZNIPXjcJXSQwXPO9tEe-v4VSqgD0aKHqPxYog4N6Cz1lKph1U1sYDSI67_bLL7elg_vkjfMp5_W5l5LuUYGMeh6hxQIaIUXf9EwV2JmvTMuZ-vBOWy0Sniy1EFo72CRTvmtrIf5AROo5MNliY3KtUxeP-SOmD-LEYwW9SlkohYzMVAZDDOrVbv7KVRHpeYNaK75KEQqdCEEkS_rskZS-Qtt_nlegTWh1mEYaA", "key": { "kty": "RSA", "kid": "samwise.gamgee@hobbiton.example", "use": "enc", "n": "wbdxI55VaanZXPY29Lg5hdmv2XhvqAhoxUkanfzf2-5zVUxa6prHRrI4pP1AhoqJRlZfYtWWd5mmHRG2pAHIlh0ySJ9wi0BioZBl1XP2e-C-FyXJGcTy0HdKQWlrfhTm42EW7Vv04r4gfao6uxjLGwfpGrZLarohiWCPnkNrg71S2CuNZSQBIPGjXfkmIy2tl_VWgGnL22GplyXj5YlBLdxXp3XeStsqo571utNfoUTU8E4qdzJ3U1DItoVkPGsMwlmmnJiwA7sXRItBCivR4M5qnZtdw-7v4WuR4779ubDuJ5nalMv2S66-RPcnFAzWSKxtBDnFJJDGIUe7Tzizjg1nms0Xq_yPub_UOlWn0ec85FCft1hACpWG8schrOBeNqHBODFskYpUc2LC5JA2TaPF2dA67dg1TTsC_FupfQ2kNGcE1LgprxKHcVWYQb86B-HozjHZcqtauBzFNV5tbTuB-TpkcvJfNcFLlH3b8mb-H_ox35FjqBSAjLKyoeqfKTpVjvXhd09knwgJf6VKq6UC418_TOljMVfFTWXUxlnfhOOnzW6HSSzD1c9WrCuVzsUMv54szidQ9wf1cYWf3g5qFDxDQKis99gcDaiCAwM3yEBIzuNeeCa5dartHDb1xEB_HcHSeYbghbMjGfasvKn0aZRsnTyC0xhWBlsolZE", "e": "AQAB", "alg": "RSA-OAEP", "d": "n7fzJc3_WG59VEOBTkayzuSMM780OJQuZjN_KbH8lOZG25ZoA7T4Bxcc0xQn5oZE5uSCIwg91oCt0JvxPcpmqzaJZg1nirjcWZ-oBtVk7gCAWq-B3qhfF3izlbkosrzjHajIcY33HBhsy4_WerrXg4MDNE4HYojy68TcxT2LYQRxUOCf5TtJXvM8olexlSGtVnQnDRutxEUCwiewfmmrfveEogLx9EA-KMgAjTiISXxqIXQhWUQX1G7v_mV_Hr2YuImYcNcHkRvp9E7ook0876DhkO8v4UOZLwA1OlUX98mkoqwc58A_Y2lBYbVx1_s5lpPsEqbbH-nqIjh1fL0gdNfihLxnclWtW7pCztLnImZAyeCWAG7ZIfv-Rn9fLIv9jZ6r7r-MSH9sqbuziHN2grGjD_jfRluMHa0l84fFKl6bcqN1JWxPVhzNZo01yDF-1LiQnqUYSepPf6X3a2SOdkqBRiquE6EvLuSYIDpJq3jDIsgoL8Mo1LoomgiJxUwL_GWEOGu28gplyzm-9Q0U0nyhEf1uhSR8aJAQWAiFImWH5W_IQT9I7-yrindr_2fWQ_i1UgMsGzA7aOGzZfPljRy6z-tY_KuBG00-28S_aWvjyUc-Alp8AUyKjBZ-7CWH32fGWK48j1t-zomrwjL_mnhsPbGs0c9WsWgRzI-K8gE", "p": "7_2v3OQZzlPFcHyYfLABQ3XP85Es4hCdwCkbDeltaUXgVy9l9etKghvM4hRkOvbb01kYVuLFmxIkCDtpi-zLCYAdXKrAK3PtSbtzld_XZ9nlsYa_QZWpXB_IrtFjVfdKUdMz94pHUhFGFj7nr6NNxfpiHSHWFE1zD_AC3mY46J961Y2LRnreVwAGNw53p07Db8yD_92pDa97vqcZOdgtybH9q6uma-RFNhO1AoiJhYZj69hjmMRXx-x56HO9cnXNbmzNSCFCKnQmn4GQLmRj9sfbZRqL94bbtE4_e0Zrpo8RNo8vxRLqQNwIy85fc6BRgBJomt8QdQvIgPgWCv5HoQ", "q": "zqOHk1P6WN_rHuM7ZF1cXH0x6RuOHq67WuHiSknqQeefGBA9PWs6ZyKQCO-O6mKXtcgE8_Q_hA2kMRcKOcvHil1hqMCNSXlflM7WPRPZu2qCDcqssd_uMbP-DqYthH_EzwL9KnYoH7JQFxxmcv5An8oXUtTwk4knKjkIYGRuUwfQTus0w1NfjFAyxOOiAQ37ussIcE6C6ZSsM3n41UlbJ7TCqewzVJaPJN5cxjySPZPD3Vp01a9YgAD6a3IIaKJdIxJS1ImnfPevSJQBE79-EXe2kSwVgOzvt-gsmM29QQ8veHy4uAqca5dZzMs7hkkHtw1z0jHV90epQJJlXXnH8Q", "dp": "19oDkBh1AXelMIxQFm2zZTqUhAzCIr4xNIGEPNoDt1jK83_FJA-xnx5kA7-1erdHdms_Ef67HsONNv5A60JaR7w8LHnDiBGnjdaUmmuO8XAxQJ_ia5mxjxNjS6E2yD44USo2JmHvzeeNczq25elqbTPLhUpGo1IZuG72FZQ5gTjXoTXC2-xtCDEUZfaUNh4IeAipfLugbpe0JAFlFfrTDAMUFpC3iXjxqzbEanflwPvj6V9iDSgjj8SozSM0dLtxvu0LIeIQAeEgT_yXcrKGmpKdSO08kLBx8VUjkbv_3Pn20Gyu2YEuwpFlM_H1NikuxJNKFGmnAq9LcnwwT0jvoQ", "dq": "S6p59KrlmzGzaQYQM3o0XfHCGvfqHLYjCO557HYQf72O9kLMCfd_1VBEqeD-1jjwELKDjck8kOBl5UvohK1oDfSP1DleAy-cnmL29DqWmhgwM1ip0CCNmkmsmDSlqkUXDi6sAaZuntyukyflI-qSQ3C_BafPyFaKrt1fgdyEwYa08pESKwwWisy7KnmoUvaJ3SaHmohFS78TJ25cfc10wZ9hQNOrIChZlkiOdFCtxDqdmCqNacnhgE3bZQjGp3n83ODSz9zwJcSUvODlXBPc2AycH6Ci5yjbxt4Ppox_5pjm6xnQkiPgj01GpsUssMmBN7iHVsrE7N2iznBNCeOUIQ", "qi": "FZhClBMywVVjnuUud-05qd5CYU0dK79akAgy9oX6RX6I3IIIPckCciRrokxglZn-omAY5CnCe4KdrnjFOT5YUZE7G_Pg44XgCXaarLQf4hl80oPEf6-jJ5Iy6wPRx7G2e8qLxnh9cOdf-kRqgOS3F48Ucvw3ma5V6KGMwQqWFeV31XtZ8l5cVI-I3NzBS7qltpUVgz2Ju021eyc7IlqgzR98qKONl27DuEES0aK0WE97jnsyO27Yp88Wa2RiBrEocM89QZI1seJiGDizHRUP4UZxw9zsXww46wy0P6f9grnYp7t8LkyDDk8eoI4KX6SNMNVcyVS9IWjlq8EzqZEKIA" }, "alg": "RSA-OAEP", "enc": "A128GCM" }, "generated": { "cek": "0RHSNYwN-6-2QBGsYTZLSQ", "iv": "GbX1i9kXz0sxXPmA" }, "encrypting_key": { "encrypted_key": "a0JHRoITfpX4qRewImjlStn8m3CPxBV1ueYlVhjurCyrBg3I7YhCRYjphDOOS4E7rXbr2Fn6NyQq-A-gqT0FXqNjVOGrG-bi13mwy7RoYhjTkBEC6P7sMYMXXx4gzMedpiJHQVeyI-zkZV7A9matpgevAJWrXzOUysYGTtwoSN6gtUVtlLaivjvb21O0ul4YxSHV-ByK1kyeetRp_fuYJxHoKLQL9P424sKx2WGYb4zsBIPF4ssl_e5IR7nany-25_UmC2urosNkoFz9cQ82MypZP8gqbQJyPN-Fpp4Z-5o6yV64x6yzDUF_5JCIdl-Qv6H5dMVIY7q1eKpXcV1lWO_2FefEBqXxXvIjLeZivjNkzogCq3-IapSjVFnMjBxjpYLT8muaawo1yy1XXMuinIpNcOY3n4KKrXLrCcteX85m4IIHMZa38s1Hpr56fPPseMA-Jltmt-a9iEDtOzhtxz8AXy9tsCAZV2XBWNG8c3kJusAamBKOYwfk7JhLRDgOnJjlJLhn7TI4UxDp9dCmUXEN6z0v23W15qJIEXNJtqnblpymooeWAHCT4e_Owbim1g0AEpTHUdA2iiLNs9WTX_H_TXuPC8yDDhi1smxS_X_xpkIHkiIHWDOLx03BpqDTivpKkBYwqP2UZkcxqX2Fo_GnVrNwlK7Lgxw6FSQvDO0" }, "encrypting_content": { "protected": { "alg": "RSA-OAEP", "cty": "JWT", "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJSU0EtT0FFUCIsImN0eSI6IkpXVCIsImVuYyI6IkExMjhHQ00ifQ", "ciphertext": "SZI4IvKHmwpazl_pJQXX3mHv1ANnOU4Wf9-utWYUcKrBNgCe2OFMf66cSJ8k2QkxaQD3_R60MGE9ofomwtky3GFxMeGRjtpMt9OAvVLsAXB0_UTCBGyBg3C2bWLXqZlfJAAoJRUPRk-BimYZY81zVBuIhc7HsQePCpu33SzMsFHjn4lP_idrJz_glZTNgKDt8zdnUPauKTKDNOH1DD4fuzvDYfDIAfqGPyL5sVRwbiXpXdGokEszM-9ChMPqW1QNhzuX_Zul3bvrJwr7nuGZs4cUScY3n8yE3AHCLurgls-A9mz1X38xEaulV18l4Fg9tLejdkAuQZjPbqeHQBJe4IwGD5Ee0dQ-Mtz4NnhkIWx-YKBb_Xo2zI3Q_1sYjKUuis7yWW-HTr_vqvFt0bj7WJf2vzB0TZ3dvsoGaTvPH2dyWwumUrlx4gmPUzBdwTO6ubfYSDUEEz5py0d_OtWeUSYcCYBKD-aM7tXg26qJo21gYjLfhn9zy-W19sOCZGuzgFjPhawXHpvnj_t-0_ES96kogjJLxS1IMU9Y5XmnwZMyNc9EIwnogsCg-hVuvzyP0sIruktmI94_SL1xgMl7o03phcTMxtlMizR88NKU1WkBsiXMCjy1Noue7MD-ShDp5dmM", "tag": "KnIKEhN8U-3C9s4gtSpjSw" }, "output": { "compact": "eyJhbGciOiJSU0EtT0FFUCIsImN0eSI6IkpXVCIsImVuYyI6IkExMjhHQ00ifQ.a0JHRoITfpX4qRewImjlStn8m3CPxBV1ueYlVhjurCyrBg3I7YhCRYjphDOOS4E7rXbr2Fn6NyQq-A-gqT0FXqNjVOGrG-bi13mwy7RoYhjTkBEC6P7sMYMXXx4gzMedpiJHQVeyI-zkZV7A9matpgevAJWrXzOUysYGTtwoSN6gtUVtlLaivjvb21O0ul4YxSHV-ByK1kyeetRp_fuYJxHoKLQL9P424sKx2WGYb4zsBIPF4ssl_e5IR7nany-25_UmC2urosNkoFz9cQ82MypZP8gqbQJyPN-Fpp4Z-5o6yV64x6yzDUF_5JCIdl-Qv6H5dMVIY7q1eKpXcV1lWO_2FefEBqXxXvIjLeZivjNkzogCq3-IapSjVFnMjBxjpYLT8muaawo1yy1XXMuinIpNcOY3n4KKrXLrCcteX85m4IIHMZa38s1Hpr56fPPseMA-Jltmt-a9iEDtOzhtxz8AXy9tsCAZV2XBWNG8c3kJusAamBKOYwfk7JhLRDgOnJjlJLhn7TI4UxDp9dCmUXEN6z0v23W15qJIEXNJtqnblpymooeWAHCT4e_Owbim1g0AEpTHUdA2iiLNs9WTX_H_TXuPC8yDDhi1smxS_X_xpkIHkiIHWDOLx03BpqDTivpKkBYwqP2UZkcxqX2Fo_GnVrNwlK7Lgxw6FSQvDO0.GbX1i9kXz0sxXPmA.SZI4IvKHmwpazl_pJQXX3mHv1ANnOU4Wf9-utWYUcKrBNgCe2OFMf66cSJ8k2QkxaQD3_R60MGE9ofomwtky3GFxMeGRjtpMt9OAvVLsAXB0_UTCBGyBg3C2bWLXqZlfJAAoJRUPRk-BimYZY81zVBuIhc7HsQePCpu33SzMsFHjn4lP_idrJz_glZTNgKDt8zdnUPauKTKDNOH1DD4fuzvDYfDIAfqGPyL5sVRwbiXpXdGokEszM-9ChMPqW1QNhzuX_Zul3bvrJwr7nuGZs4cUScY3n8yE3AHCLurgls-A9mz1X38xEaulV18l4Fg9tLejdkAuQZjPbqeHQBJe4IwGD5Ee0dQ-Mtz4NnhkIWx-YKBb_Xo2zI3Q_1sYjKUuis7yWW-HTr_vqvFt0bj7WJf2vzB0TZ3dvsoGaTvPH2dyWwumUrlx4gmPUzBdwTO6ubfYSDUEEz5py0d_OtWeUSYcCYBKD-aM7tXg26qJo21gYjLfhn9zy-W19sOCZGuzgFjPhawXHpvnj_t-0_ES96kogjJLxS1IMU9Y5XmnwZMyNc9EIwnogsCg-hVuvzyP0sIruktmI94_SL1xgMl7o03phcTMxtlMizR88NKU1WkBsiXMCjy1Noue7MD-ShDp5dmM.KnIKEhN8U-3C9s4gtSpjSw", "json": { "recipients": [ { "encrypted_key": "a0JHRoITfpX4qRewImjlStn8m3CPxBV1ueYlVhjurCyrBg3I7YhCRYjphDOOS4E7rXbr2Fn6NyQq-A-gqT0FXqNjVOGrG-bi13mwy7RoYhjTkBEC6P7sMYMXXx4gzMedpiJHQVeyI-zkZV7A9matpgevAJWrXzOUysYGTtwoSN6gtUVtlLaivjvb21O0ul4YxSHV-ByK1kyeetRp_fuYJxHoKLQL9P424sKx2WGYb4zsBIPF4ssl_e5IR7nany-25_UmC2urosNkoFz9cQ82MypZP8gqbQJyPN-Fpp4Z-5o6yV64x6yzDUF_5JCIdl-Qv6H5dMVIY7q1eKpXcV1lWO_2FefEBqXxXvIjLeZivjNkzogCq3-IapSjVFnMjBxjpYLT8muaawo1yy1XXMuinIpNcOY3n4KKrXLrCcteX85m4IIHMZa38s1Hpr56fPPseMA-Jltmt-a9iEDtOzhtxz8AXy9tsCAZV2XBWNG8c3kJusAamBKOYwfk7JhLRDgOnJjlJLhn7TI4UxDp9dCmUXEN6z0v23W15qJIEXNJtqnblpymooeWAHCT4e_Owbim1g0AEpTHUdA2iiLNs9WTX_H_TXuPC8yDDhi1smxS_X_xpkIHkiIHWDOLx03BpqDTivpKkBYwqP2UZkcxqX2Fo_GnVrNwlK7Lgxw6FSQvDO0" } ], "protected": "eyJhbGciOiJSU0EtT0FFUCIsImN0eSI6IkpXVCIsImVuYyI6IkExMjhHQ00ifQ", "iv": "GbX1i9kXz0sxXPmA", "ciphertext": "SZI4IvKHmwpazl_pJQXX3mHv1ANnOU4Wf9-utWYUcKrBNgCe2OFMf66cSJ8k2QkxaQD3_R60MGE9ofomwtky3GFxMeGRjtpMt9OAvVLsAXB0_UTCBGyBg3C2bWLXqZlfJAAoJRUPRk-BimYZY81zVBuIhc7HsQePCpu33SzMsFHjn4lP_idrJz_glZTNgKDt8zdnUPauKTKDNOH1DD4fuzvDYfDIAfqGPyL5sVRwbiXpXdGokEszM-9ChMPqW1QNhzuX_Zul3bvrJwr7nuGZs4cUScY3n8yE3AHCLurgls-A9mz1X38xEaulV18l4Fg9tLejdkAuQZjPbqeHQBJe4IwGD5Ee0dQ-Mtz4NnhkIWx-YKBb_Xo2zI3Q_1sYjKUuis7yWW-HTr_vqvFt0bj7WJf2vzB0TZ3dvsoGaTvPH2dyWwumUrlx4gmPUzBdwTO6ubfYSDUEEz5py0d_OtWeUSYcCYBKD-aM7tXg26qJo21gYjLfhn9zy-W19sOCZGuzgFjPhawXHpvnj_t-0_ES96kogjJLxS1IMU9Y5XmnwZMyNc9EIwnogsCg-hVuvzyP0sIruktmI94_SL1xgMl7o03phcTMxtlMizR88NKU1WkBsiXMCjy1Noue7MD-ShDp5dmM", "tag": "KnIKEhN8U-3C9s4gtSpjSw" }, "json_flat": { "encrypted_key": "a0JHRoITfpX4qRewImjlStn8m3CPxBV1ueYlVhjurCyrBg3I7YhCRYjphDOOS4E7rXbr2Fn6NyQq-A-gqT0FXqNjVOGrG-bi13mwy7RoYhjTkBEC6P7sMYMXXx4gzMedpiJHQVeyI-zkZV7A9matpgevAJWrXzOUysYGTtwoSN6gtUVtlLaivjvb21O0ul4YxSHV-ByK1kyeetRp_fuYJxHoKLQL9P424sKx2WGYb4zsBIPF4ssl_e5IR7nany-25_UmC2urosNkoFz9cQ82MypZP8gqbQJyPN-Fpp4Z-5o6yV64x6yzDUF_5JCIdl-Qv6H5dMVIY7q1eKpXcV1lWO_2FefEBqXxXvIjLeZivjNkzogCq3-IapSjVFnMjBxjpYLT8muaawo1yy1XXMuinIpNcOY3n4KKrXLrCcteX85m4IIHMZa38s1Hpr56fPPseMA-Jltmt-a9iEDtOzhtxz8AXy9tsCAZV2XBWNG8c3kJusAamBKOYwfk7JhLRDgOnJjlJLhn7TI4UxDp9dCmUXEN6z0v23W15qJIEXNJtqnblpymooeWAHCT4e_Owbim1g0AEpTHUdA2iiLNs9WTX_H_TXuPC8yDDhi1smxS_X_xpkIHkiIHWDOLx03BpqDTivpKkBYwqP2UZkcxqX2Fo_GnVrNwlK7Lgxw6FSQvDO0", "protected": "eyJhbGciOiJSU0EtT0FFUCIsImN0eSI6IkpXVCIsImVuYyI6IkExMjhHQ00ifQ", "iv": "GbX1i9kXz0sxXPmA", "ciphertext": "SZI4IvKHmwpazl_pJQXX3mHv1ANnOU4Wf9-utWYUcKrBNgCe2OFMf66cSJ8k2QkxaQD3_R60MGE9ofomwtky3GFxMeGRjtpMt9OAvVLsAXB0_UTCBGyBg3C2bWLXqZlfJAAoJRUPRk-BimYZY81zVBuIhc7HsQePCpu33SzMsFHjn4lP_idrJz_glZTNgKDt8zdnUPauKTKDNOH1DD4fuzvDYfDIAfqGPyL5sVRwbiXpXdGokEszM-9ChMPqW1QNhzuX_Zul3bvrJwr7nuGZs4cUScY3n8yE3AHCLurgls-A9mz1X38xEaulV18l4Fg9tLejdkAuQZjPbqeHQBJe4IwGD5Ee0dQ-Mtz4NnhkIWx-YKBb_Xo2zI3Q_1sYjKUuis7yWW-HTr_vqvFt0bj7WJf2vzB0TZ3dvsoGaTvPH2dyWwumUrlx4gmPUzBdwTO6ubfYSDUEEz5py0d_OtWeUSYcCYBKD-aM7tXg26qJo21gYjLfhn9zy-W19sOCZGuzgFjPhawXHpvnj_t-0_ES96kogjJLxS1IMU9Y5XmnwZMyNc9EIwnogsCg-hVuvzyP0sIruktmI94_SL1xgMl7o03phcTMxtlMizR88NKU1WkBsiXMCjy1Noue7MD-ShDp5dmM", "tag": "KnIKEhN8U-3C9s4gtSpjSw" } } } } rhonabwy-1.1.13/test/cookbook-master/LICENSE000066400000000000000000000022731452472117100205210ustar00rootroot00000000000000This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to rhonabwy-1.1.13/test/cookbook-master/README.md000066400000000000000000000013221452472117100207650ustar00rootroot00000000000000# JOSE Cookbook # This repository contains all of the examples from [Examples of Protecting Content using JavaScript Object Signing and Encryption (JOSE)](https://tools.ietf.org/html/draft-ietf-jose-cookbook) -- affectionately known as the "JOSE Cookbook" -- in a machine-readable format. The repository has three directories: * 'jwk' containing the JSON Web Key (JWK) examples * 'jws' containing the JSON Web Signature (JWS) examples * 'jwe' containing the JSON Web Encryption (JWE) examples * 'rfc7797' contains examples with b64=false * 'curve25519' contains examples for the 25519 and 448 CFRG curves Also included is "6.nesting_signatures_and_encryption.json" which contains the example nesting a JWS into a JWE. rhonabwy-1.1.13/test/cookbook-master/curve25519/000077500000000000000000000000001452472117100212425ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/curve25519/README.md000066400000000000000000000003601452472117100225200ustar00rootroot00000000000000# CFRG Curves 25519 and 448 Examples # This repository contains the signature example from [CFRG ECDH and signatures in JOSE](https://tools.ietf.org/html/draft-ietf-jose-cfrg-curves) as well as some examples which are not in the document. rhonabwy-1.1.13/test/cookbook-master/curve25519/ecdh-es.json000066400000000000000000000073211452472117100234500ustar00rootroot00000000000000{ "title": "Curve25519 ECDH", "reproducible": false, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "OKP", "kid": "Bob", "use": "enc", "crv": "X25519", "x": "3p7bfXt9wbTTW2HC7OQ1Nz-DQ8hbeGdNrfx-FG-IK08", "d": "XasIfmJKikt54X-Lg4AO5m87sSkmGLb9HC-LJ_-I4Os" }, "alg": "ECDH-ES", "enc": "A128GCM" }, "generated": { "iv": "0tCoBvRfolezYjpJ" }, "encrypting_key": { "epk": { "kty": "OKP", "crv": "X25519", "x": "hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo", "d": "RVqkt2ZmEiUY-OGyag9rXe7vsDm2BQ_XykdxhLv9pd4" }, "cek": "hzHdlfQIAEehb8Hrd_mFRhKsKLEzPfshfXs9l6areCc" }, "encrypting_content": { "protected": { "alg": "ECDH-ES", "kid": "Bob", "epk": { "kty": "OKP", "crv": "X25519", "x": "xvXHh3Q2S4VotXgBddGWD_KhnzYZ_euB2eaekLvvADU" }, "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoiQm9iIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJ4dlhIaDNRMlM0Vm90WGdCZGRHV0RfS2huellaX2V1QjJlYWVrTHZ2QURVIn0sImVuYyI6IkExMjhHQ00ifQ", "ciphertext": "cX3qZ4cfxiyr_Leem1b69MeLo-BHsMJy6RetGse91pgXjR7X87k1e7dJliYfzgseMV9dcVo3i1cAPeU2jkDCxrjxIBW0iUlF3JfkVH7DU3B8GxzkblOJKwJE58Sd0rJEN9rSwfLf66sbTiY_vGYf7cZhbWhj6wwBnICFfaRh_2NubCdma7zX_vsdaGJXHn-6-jjR9UaQUbJD-tPn5UAW8Sa9lPAcncYZywscUM-FET3tePOH2h_xv_LFGuN2KYJ3BED_Eyo--oSX17DD7ksSt0wfzy_TWczaG1E_TWn4nvP6T6d5nMp9OdfLWQNopQHoQGWlPbaRLHCk2mNl1K5GsJ6Q4tjSdFWpqRDpQUz2eYAk", "tag": "Yd4jUyp_PC5cACOwaAGwUQ" }, "output": { "compact": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoiQm9iIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJ4dlhIaDNRMlM0Vm90WGdCZGRHV0RfS2huellaX2V1QjJlYWVrTHZ2QURVIn0sImVuYyI6IkExMjhHQ00ifQ..0tCoBvRfolezYjpJ.cX3qZ4cfxiyr_Leem1b69MeLo-BHsMJy6RetGse91pgXjR7X87k1e7dJliYfzgseMV9dcVo3i1cAPeU2jkDCxrjxIBW0iUlF3JfkVH7DU3B8GxzkblOJKwJE58Sd0rJEN9rSwfLf66sbTiY_vGYf7cZhbWhj6wwBnICFfaRh_2NubCdma7zX_vsdaGJXHn-6-jjR9UaQUbJD-tPn5UAW8Sa9lPAcncYZywscUM-FET3tePOH2h_xv_LFGuN2KYJ3BED_Eyo--oSX17DD7ksSt0wfzy_TWczaG1E_TWn4nvP6T6d5nMp9OdfLWQNopQHoQGWlPbaRLHCk2mNl1K5GsJ6Q4tjSdFWpqRDpQUz2eYAk.Yd4jUyp_PC5cACOwaAGwUQ", "json": { "protected": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoiQm9iIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJ4dlhIaDNRMlM0Vm90WGdCZGRHV0RfS2huellaX2V1QjJlYWVrTHZ2QURVIn0sImVuYyI6IkExMjhHQ00ifQ", "iv": "0tCoBvRfolezYjpJ", "ciphertext": "cX3qZ4cfxiyr_Leem1b69MeLo-BHsMJy6RetGse91pgXjR7X87k1e7dJliYfzgseMV9dcVo3i1cAPeU2jkDCxrjxIBW0iUlF3JfkVH7DU3B8GxzkblOJKwJE58Sd0rJEN9rSwfLf66sbTiY_vGYf7cZhbWhj6wwBnICFfaRh_2NubCdma7zX_vsdaGJXHn-6-jjR9UaQUbJD-tPn5UAW8Sa9lPAcncYZywscUM-FET3tePOH2h_xv_LFGuN2KYJ3BED_Eyo--oSX17DD7ksSt0wfzy_TWczaG1E_TWn4nvP6T6d5nMp9OdfLWQNopQHoQGWlPbaRLHCk2mNl1K5GsJ6Q4tjSdFWpqRDpQUz2eYAk", "tag": "Yd4jUyp_PC5cACOwaAGwUQ" }, "json_flat": { "protected": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoiQm9iIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJ4dlhIaDNRMlM0Vm90WGdCZGRHV0RfS2huellaX2V1QjJlYWVrTHZ2QURVIn0sImVuYyI6IkExMjhHQ00ifQ", "iv": "0tCoBvRfolezYjpJ", "ciphertext": "cX3qZ4cfxiyr_Leem1b69MeLo-BHsMJy6RetGse91pgXjR7X87k1e7dJliYfzgseMV9dcVo3i1cAPeU2jkDCxrjxIBW0iUlF3JfkVH7DU3B8GxzkblOJKwJE58Sd0rJEN9rSwfLf66sbTiY_vGYf7cZhbWhj6wwBnICFfaRh_2NubCdma7zX_vsdaGJXHn-6-jjR9UaQUbJD-tPn5UAW8Sa9lPAcncYZywscUM-FET3tePOH2h_xv_LFGuN2KYJ3BED_Eyo--oSX17DD7ksSt0wfzy_TWczaG1E_TWn4nvP6T6d5nMp9OdfLWQNopQHoQGWlPbaRLHCk2mNl1K5GsJ6Q4tjSdFWpqRDpQUz2eYAk", "tag": "Yd4jUyp_PC5cACOwaAGwUQ" } } }rhonabwy-1.1.13/test/cookbook-master/curve25519/jws.json000066400000000000000000000024561452472117100227470ustar00rootroot00000000000000{ "title": "Ed25519 signing", "reproducible": true, "input": { "payload": "Example of Ed25519 signing", "key": { "kty": "OKP", "use": "sig", "crv": "Ed25519", "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo", "d": "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A" }, "alg": "EdDSA" }, "signing": { "protected": { "alg": "EdDSA" }, "protected_b64u": "eyJhbGciOiJFZERTQSJ9", "sig-input": "eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc", "sig": "hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg" }, "output": { "compact": "eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc.hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg", "json": { "payload": "RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc", "signatures": [ { "protected": "eyJhbGciOiJFZERTQSJ9", "signature": "hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg" } ] }, "json_flat": { "payload": "RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc", "protected": "eyJhbGciOiJFZERTQSJ9", "signature": "hgyY0il_MGCjP0JzlnLWG1PPOt7-09PGcvMg3AIbQR6dWbhijcNR4ki4iylGjg5BhVsPt9g7sVvpAr_MuM0KAg" } } }rhonabwy-1.1.13/test/cookbook-master/jwe/000077500000000000000000000000001452472117100202755ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jwe/5_1.key_encryption_using_rsa_v15_and_aes-hmac-sha2.json000066400000000000000000000144361452472117100326050ustar00rootroot00000000000000{ "title": "Key Encryption using RSA v1.5 and AES-HMAC-SHA2", "reproducible": false, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "RSA", "kid": "frodo.baggins@hobbiton.example", "use": "enc", "n": "maxhbsmBtdQ3CNrKvprUE6n9lYcregDMLYNeTAWcLj8NnPU9XIYegTHVHQjxKDSHP2l-F5jS7sppG1wgdAqZyhnWvXhYNvcM7RfgKxqNx_xAHx6f3yy7s-M9PSNCwPC2lh6UAkR4I00EhV9lrypM9Pi4lBUop9t5fS9W5UNwaAllhrd-osQGPjIeI1deHTwx-ZTHu3C60Pu_LJIl6hKn9wbwaUmA4cR5Bd2pgbaY7ASgsjCUbtYJaNIHSoHXprUdJZKUMAzV0WOKPfA6OPI4oypBadjvMZ4ZAj3BnXaSYsEZhaueTXvZB4eZOAjIyh2e_VOIKVMsnDrJYAVotGlvMQ", "e": "AQAB", "d": "Kn9tgoHfiTVi8uPu5b9TnwyHwG5dK6RE0uFdlpCGnJN7ZEi963R7wybQ1PLAHmpIbNTztfrheoAniRV1NCIqXaW_qS461xiDTp4ntEPnqcKsyO5jMAji7-CL8vhpYYowNFvIesgMoVaPRYMYT9TW63hNM0aWs7USZ_hLg6Oe1mY0vHTI3FucjSM86Nff4oIENt43r2fspgEPGRrdE6fpLc9Oaq-qeP1GFULimrRdndm-P8q8kvN3KHlNAtEgrQAgTTgz80S-3VD0FgWfgnb1PNmiuPUxO8OpI9KDIfu_acc6fg14nsNaJqXe6RESvhGPH2afjHqSy_Fd2vpzj85bQQ", "p": "2DwQmZ43FoTnQ8IkUj3BmKRf5Eh2mizZA5xEJ2MinUE3sdTYKSLtaEoekX9vbBZuWxHdVhM6UnKCJ_2iNk8Z0ayLYHL0_G21aXf9-unynEpUsH7HHTklLpYAzOOx1ZgVljoxAdWNn3hiEFrjZLZGS7lOH-a3QQlDDQoJOJ2VFmU", "q": "te8LY4-W7IyaqH1ExujjMqkTAlTeRbv0VLQnfLY2xINnrWdwiQ93_VF099aP1ESeLja2nw-6iKIe-qT7mtCPozKfVtUYfz5HrJ_XY2kfexJINb9lhZHMv5p1skZpeIS-GPHCC6gRlKo1q-idn_qxyusfWv7WAxlSVfQfk8d6Et0", "dp": "UfYKcL_or492vVc0PzwLSplbg4L3-Z5wL48mwiswbpzOyIgd2xHTHQmjJpFAIZ8q-zf9RmgJXkDrFs9rkdxPtAsL1WYdeCT5c125Fkdg317JVRDo1inX7x2Kdh8ERCreW8_4zXItuTl_KiXZNU5lvMQjWbIw2eTx1lpsflo0rYU", "dq": "iEgcO-QfpepdH8FWd7mUFyrXdnOkXJBCogChY6YKuIHGc_p8Le9MbpFKESzEaLlN1Ehf3B6oGBl5Iz_ayUlZj2IoQZ82znoUrpa9fVYNot87ACfzIG7q9Mv7RiPAderZi03tkVXAdaBau_9vs5rS-7HMtxkVrxSUvJY14TkXlHE", "qi": "kC-lzZOqoFaZCr5l0tOVtREKoVqaAYhQiqIRGL-MzS4sCmRkxm5vZlXYx6RtE1n_AagjqajlkjieGlxTTThHD8Iga6foGBMaAr5uR1hGQpSc7Gl7CF1DZkBJMTQN6EshYzZfxW08mIO8M6Rzuh0beL6fG9mkDcIyPrBXx2bQ_mM" }, "alg": "RSA1_5", "enc": "A128CBC-HS256" }, "generated": { "cek": "3qyTVhIWt5juqZUCpfRqpvauwB956MEJL2Rt-8qXKSo", "iv": "bbd5sTkYwhAIqfHsx8DayA" }, "encrypting_key": { "encrypted_key": "laLxI0j-nLH-_BgLOXMozKxmy9gffy2gTdvqzfTihJBuuzxg0V7yk1WClnQePFvG2K-pvSlWc9BRIazDrn50RcRai__3TDON395H3c62tIouJJ4XaRvYHFjZTZ2GXfz8YAImcc91Tfk0WXC2F5Xbb71ClQ1DDH151tlpH77f2ff7xiSxh9oSewYrcGTSLUeeCt36r1Kt3OSj7EyBQXoZlN7IxbyhMAfgIe7Mv1rOTOI5I8NQqeXXW8VlzNmoxaGMny3YnGir5Wf6Qt2nBq4qDaPdnaAuuGUGEecelIO1wx1BpyIfgvfjOhMBs9M8XL223Fg47xlGsMXdfuY-4jaqVw" }, "encrypting_content": { "protected": { "alg": "RSA1_5", "kid": "frodo.baggins@hobbiton.example", "enc": "A128CBC-HS256" }, "protected_b64u": "eyJhbGciOiJSU0ExXzUiLCJraWQiOiJmcm9kby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "ciphertext": "0fys_TY_na7f8dwSfXLiYdHaA2DxUjD67ieF7fcVbIR62JhJvGZ4_FNVSiGc_raa0HnLQ6s1P2sv3Xzl1p1l_o5wR_RsSzrS8Z-wnI3Jvo0mkpEEnlDmZvDu_k8OWzJv7eZVEqiWKdyVzFhPpiyQU28GLOpRc2VbVbK4dQKPdNTjPPEmRqcaGeTWZVyeSUvf5k59yJZxRuSvWFf6KrNtmRdZ8R4mDOjHSrM_s8uwIFcqt4r5GX8TKaI0zT5CbL5Qlw3sRc7u_hg0yKVOiRytEAEs3vZkcfLkP6nbXdC_PkMdNS-ohP78T2O6_7uInMGhFeX4ctHG7VelHGiT93JfWDEQi5_V9UN1rhXNrYu-0fVMkZAKX3VWi7lzA6BP430m", "tag": "kvKuFBXHe5mQr4lqgobAUg" }, "output": { "compact": "eyJhbGciOiJSU0ExXzUiLCJraWQiOiJmcm9kby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.laLxI0j-nLH-_BgLOXMozKxmy9gffy2gTdvqzfTihJBuuzxg0V7yk1WClnQePFvG2K-pvSlWc9BRIazDrn50RcRai__3TDON395H3c62tIouJJ4XaRvYHFjZTZ2GXfz8YAImcc91Tfk0WXC2F5Xbb71ClQ1DDH151tlpH77f2ff7xiSxh9oSewYrcGTSLUeeCt36r1Kt3OSj7EyBQXoZlN7IxbyhMAfgIe7Mv1rOTOI5I8NQqeXXW8VlzNmoxaGMny3YnGir5Wf6Qt2nBq4qDaPdnaAuuGUGEecelIO1wx1BpyIfgvfjOhMBs9M8XL223Fg47xlGsMXdfuY-4jaqVw.bbd5sTkYwhAIqfHsx8DayA.0fys_TY_na7f8dwSfXLiYdHaA2DxUjD67ieF7fcVbIR62JhJvGZ4_FNVSiGc_raa0HnLQ6s1P2sv3Xzl1p1l_o5wR_RsSzrS8Z-wnI3Jvo0mkpEEnlDmZvDu_k8OWzJv7eZVEqiWKdyVzFhPpiyQU28GLOpRc2VbVbK4dQKPdNTjPPEmRqcaGeTWZVyeSUvf5k59yJZxRuSvWFf6KrNtmRdZ8R4mDOjHSrM_s8uwIFcqt4r5GX8TKaI0zT5CbL5Qlw3sRc7u_hg0yKVOiRytEAEs3vZkcfLkP6nbXdC_PkMdNS-ohP78T2O6_7uInMGhFeX4ctHG7VelHGiT93JfWDEQi5_V9UN1rhXNrYu-0fVMkZAKX3VWi7lzA6BP430m.kvKuFBXHe5mQr4lqgobAUg", "json": { "recipients": [ { "encrypted_key": "laLxI0j-nLH-_BgLOXMozKxmy9gffy2gTdvqzfTihJBuuzxg0V7yk1WClnQePFvG2K-pvSlWc9BRIazDrn50RcRai__3TDON395H3c62tIouJJ4XaRvYHFjZTZ2GXfz8YAImcc91Tfk0WXC2F5Xbb71ClQ1DDH151tlpH77f2ff7xiSxh9oSewYrcGTSLUeeCt36r1Kt3OSj7EyBQXoZlN7IxbyhMAfgIe7Mv1rOTOI5I8NQqeXXW8VlzNmoxaGMny3YnGir5Wf6Qt2nBq4qDaPdnaAuuGUGEecelIO1wx1BpyIfgvfjOhMBs9M8XL223Fg47xlGsMXdfuY-4jaqVw" } ], "protected": "eyJhbGciOiJSU0ExXzUiLCJraWQiOiJmcm9kby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "iv": "bbd5sTkYwhAIqfHsx8DayA", "ciphertext": "0fys_TY_na7f8dwSfXLiYdHaA2DxUjD67ieF7fcVbIR62JhJvGZ4_FNVSiGc_raa0HnLQ6s1P2sv3Xzl1p1l_o5wR_RsSzrS8Z-wnI3Jvo0mkpEEnlDmZvDu_k8OWzJv7eZVEqiWKdyVzFhPpiyQU28GLOpRc2VbVbK4dQKPdNTjPPEmRqcaGeTWZVyeSUvf5k59yJZxRuSvWFf6KrNtmRdZ8R4mDOjHSrM_s8uwIFcqt4r5GX8TKaI0zT5CbL5Qlw3sRc7u_hg0yKVOiRytEAEs3vZkcfLkP6nbXdC_PkMdNS-ohP78T2O6_7uInMGhFeX4ctHG7VelHGiT93JfWDEQi5_V9UN1rhXNrYu-0fVMkZAKX3VWi7lzA6BP430m", "tag": "kvKuFBXHe5mQr4lqgobAUg" }, "json_flat": { "protected": "eyJhbGciOiJSU0ExXzUiLCJraWQiOiJmcm9kby5iYWdnaW5zQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "encrypted_key": "laLxI0j-nLH-_BgLOXMozKxmy9gffy2gTdvqzfTihJBuuzxg0V7yk1WClnQePFvG2K-pvSlWc9BRIazDrn50RcRai__3TDON395H3c62tIouJJ4XaRvYHFjZTZ2GXfz8YAImcc91Tfk0WXC2F5Xbb71ClQ1DDH151tlpH77f2ff7xiSxh9oSewYrcGTSLUeeCt36r1Kt3OSj7EyBQXoZlN7IxbyhMAfgIe7Mv1rOTOI5I8NQqeXXW8VlzNmoxaGMny3YnGir5Wf6Qt2nBq4qDaPdnaAuuGUGEecelIO1wx1BpyIfgvfjOhMBs9M8XL223Fg47xlGsMXdfuY-4jaqVw", "iv": "bbd5sTkYwhAIqfHsx8DayA", "ciphertext": "0fys_TY_na7f8dwSfXLiYdHaA2DxUjD67ieF7fcVbIR62JhJvGZ4_FNVSiGc_raa0HnLQ6s1P2sv3Xzl1p1l_o5wR_RsSzrS8Z-wnI3Jvo0mkpEEnlDmZvDu_k8OWzJv7eZVEqiWKdyVzFhPpiyQU28GLOpRc2VbVbK4dQKPdNTjPPEmRqcaGeTWZVyeSUvf5k59yJZxRuSvWFf6KrNtmRdZ8R4mDOjHSrM_s8uwIFcqt4r5GX8TKaI0zT5CbL5Qlw3sRc7u_hg0yKVOiRytEAEs3vZkcfLkP6nbXdC_PkMdNS-ohP78T2O6_7uInMGhFeX4ctHG7VelHGiT93JfWDEQi5_V9UN1rhXNrYu-0fVMkZAKX3VWi7lzA6BP430m", "tag": "kvKuFBXHe5mQr4lqgobAUg" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_10.including_additional_authentication_data.json000066400000000000000000000075101452472117100320720ustar00rootroot00000000000000{ "title": "Including Additional Authenticated Data", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "use": "enc", "alg": "A128KW", "k": "GZy6sIZ6wl9NJOKB-jnmVQ" }, "alg": "A128KW", "enc": "A128GCM", "aad": "[\"vcard\",[[\"version\",{},\"text\",\"4.0\"],[\"fn\",{},\"text\",\"Meriadoc Brandybuck\"],[\"n\",{},\"text\",[\"Brandybuck\",\"Meriadoc\",\"Mr.\",\"\"]],[\"bday\",{},\"text\",\"TA 2982\"],[\"gender\",{},\"text\",\"M\"]]]" }, "generated": { "cek": "75m1ALsYv10pZTKPWrsqdg", "iv": "veCx9ece2orS7c_N", "aad_b64u": "WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d" }, "encrypting_key": { "encrypted_key": "4YiiQ_ZzH76TaIkJmYfRFgOV9MIpnx4X" }, "encrypting_content": { "protected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "ciphertext": "Z_3cbr0k3bVM6N3oSNmHz7Lyf3iPppGf3Pj17wNZqteJ0Ui8p74SchQP8xygM1oFRWCNzeIa6s6BcEtp8qEFiqTUEyiNkOWDNoF14T_4NFqF-p2Mx8zkbKxI7oPK8KNarFbyxIDvICNqBLba-v3uzXBdB89fzOI-Lv4PjOFAQGHrgv1rjXAmKbgkft9cB4WeyZw8MldbBhc-V_KWZslrsLNygon_JJWd_ek6LQn5NRehvApqf9ZrxB4aq3FXBxOxCys35PhCdaggy2kfUfl2OkwKnWUbgXVD1C6HxLIlqHhCwXDG59weHrRDQeHyMRoBljoV3X_bUTJDnKBFOod7nLz-cj48JMx3SnCZTpbQAkFV", "tag": "vOaH_Rajnpy_3hOtqvZHRA" }, "output": { "json": { "recipients": [ { "encrypted_key": "4YiiQ_ZzH76TaIkJmYfRFgOV9MIpnx4X" } ], "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "iv": "veCx9ece2orS7c_N", "aad": "WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d", "ciphertext": "Z_3cbr0k3bVM6N3oSNmHz7Lyf3iPppGf3Pj17wNZqteJ0Ui8p74SchQP8xygM1oFRWCNzeIa6s6BcEtp8qEFiqTUEyiNkOWDNoF14T_4NFqF-p2Mx8zkbKxI7oPK8KNarFbyxIDvICNqBLba-v3uzXBdB89fzOI-Lv4PjOFAQGHrgv1rjXAmKbgkft9cB4WeyZw8MldbBhc-V_KWZslrsLNygon_JJWd_ek6LQn5NRehvApqf9ZrxB4aq3FXBxOxCys35PhCdaggy2kfUfl2OkwKnWUbgXVD1C6HxLIlqHhCwXDG59weHrRDQeHyMRoBljoV3X_bUTJDnKBFOod7nLz-cj48JMx3SnCZTpbQAkFV", "tag": "vOaH_Rajnpy_3hOtqvZHRA" }, "json_flat": { "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "encrypted_key": "4YiiQ_ZzH76TaIkJmYfRFgOV9MIpnx4X", "aad": "WyJ2Y2FyZCIsW1sidmVyc2lvbiIse30sInRleHQiLCI0LjAiXSxbImZuIix7fSwidGV4dCIsIk1lcmlhZG9jIEJyYW5keWJ1Y2siXSxbIm4iLHt9LCJ0ZXh0IixbIkJyYW5keWJ1Y2siLCJNZXJpYWRvYyIsIk1yLiIsIiJdXSxbImJkYXkiLHt9LCJ0ZXh0IiwiVEEgMjk4MiJdLFsiZ2VuZGVyIix7fSwidGV4dCIsIk0iXV1d", "iv": "veCx9ece2orS7c_N", "ciphertext": "Z_3cbr0k3bVM6N3oSNmHz7Lyf3iPppGf3Pj17wNZqteJ0Ui8p74SchQP8xygM1oFRWCNzeIa6s6BcEtp8qEFiqTUEyiNkOWDNoF14T_4NFqF-p2Mx8zkbKxI7oPK8KNarFbyxIDvICNqBLba-v3uzXBdB89fzOI-Lv4PjOFAQGHrgv1rjXAmKbgkft9cB4WeyZw8MldbBhc-V_KWZslrsLNygon_JJWd_ek6LQn5NRehvApqf9ZrxB4aq3FXBxOxCys35PhCdaggy2kfUfl2OkwKnWUbgXVD1C6HxLIlqHhCwXDG59weHrRDQeHyMRoBljoV3X_bUTJDnKBFOod7nLz-cj48JMx3SnCZTpbQAkFV", "tag": "vOaH_Rajnpy_3hOtqvZHRA" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_11.protecting_specific_header_fields.json000066400000000000000000000055151452472117100305230ustar00rootroot00000000000000{ "title": "Protecting Specific Header Fields", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "use": "enc", "alg": "A128KW", "k": "GZy6sIZ6wl9NJOKB-jnmVQ" }, "alg": "A128KW", "enc": "A128GCM" }, "generated": { "cek": "WDgEptBmQs9ouUvArz6x6g", "iv": "WgEJsDS9bkoXQ3nR" }, "encrypting_key": { "encrypted_key": "jJIcM9J-hbx3wnqhf5FlkEYos0sHsF0H" }, "encrypting_content": { "protected": { "enc": "A128GCM" }, "protected_b64u": "eyJlbmMiOiJBMTI4R0NNIn0", "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8" }, "ciphertext": "lIbCyRmRJxnB2yLQOTqjCDKV3H30ossOw3uD9DPsqLL2DM3swKkjOwQyZtWsFLYMj5YeLht_StAn21tHmQJuuNt64T8D4t6C7kC9OCCJ1IHAolUv4MyOt80MoPb8fZYbNKqplzYJgIL58g8N2v46OgyG637d6uuKPwhAnTGm_zWhqc_srOvgiLkzyFXPq1hBAURbc3-8BqeRb48iR1-_5g5UjWVD3lgiLCN_P7AW8mIiFvUNXBPJK3nOWL4teUPS8yHLbWeL83olU4UAgL48x-8dDkH23JykibVSQju-f7e-1xreHWXzWLHs1NqBbre0dEwK3HX_xM0LjUz77Krppgegoutpf5qaKg3l-_xMINmf", "tag": "fNYLqpUe84KD45lvDiaBAQ" }, "output": { "json": { "recipients": [ { "encrypted_key": "jJIcM9J-hbx3wnqhf5FlkEYos0sHsF0H" } ], "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8" }, "protected": "eyJlbmMiOiJBMTI4R0NNIn0", "iv": "WgEJsDS9bkoXQ3nR", "ciphertext": "lIbCyRmRJxnB2yLQOTqjCDKV3H30ossOw3uD9DPsqLL2DM3swKkjOwQyZtWsFLYMj5YeLht_StAn21tHmQJuuNt64T8D4t6C7kC9OCCJ1IHAolUv4MyOt80MoPb8fZYbNKqplzYJgIL58g8N2v46OgyG637d6uuKPwhAnTGm_zWhqc_srOvgiLkzyFXPq1hBAURbc3-8BqeRb48iR1-_5g5UjWVD3lgiLCN_P7AW8mIiFvUNXBPJK3nOWL4teUPS8yHLbWeL83olU4UAgL48x-8dDkH23JykibVSQju-f7e-1xreHWXzWLHs1NqBbre0dEwK3HX_xM0LjUz77Krppgegoutpf5qaKg3l-_xMINmf", "tag": "fNYLqpUe84KD45lvDiaBAQ" }, "json_flat": { "protected": "eyJlbmMiOiJBMTI4R0NNIn0", "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8" }, "encrypted_key": "jJIcM9J-hbx3wnqhf5FlkEYos0sHsF0H", "iv": "WgEJsDS9bkoXQ3nR", "ciphertext": "lIbCyRmRJxnB2yLQOTqjCDKV3H30ossOw3uD9DPsqLL2DM3swKkjOwQyZtWsFLYMj5YeLht_StAn21tHmQJuuNt64T8D4t6C7kC9OCCJ1IHAolUv4MyOt80MoPb8fZYbNKqplzYJgIL58g8N2v46OgyG637d6uuKPwhAnTGm_zWhqc_srOvgiLkzyFXPq1hBAURbc3-8BqeRb48iR1-_5g5UjWVD3lgiLCN_P7AW8mIiFvUNXBPJK3nOWL4teUPS8yHLbWeL83olU4UAgL48x-8dDkH23JykibVSQju-f7e-1xreHWXzWLHs1NqBbre0dEwK3HX_xM0LjUz77Krppgegoutpf5qaKg3l-_xMINmf", "tag": "fNYLqpUe84KD45lvDiaBAQ" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_12.protecting_content_only.json000066400000000000000000000053211452472117100266070ustar00rootroot00000000000000{ "title": "Protecting Content Only", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "use": "enc", "alg": "A128KW", "k": "GZy6sIZ6wl9NJOKB-jnmVQ" }, "alg": "A128KW", "enc": "A128GCM" }, "generated": { "cek": "KBooAFl30QPV3vkcZlXnzQ", "iv": "YihBoVOGsR1l7jCD" }, "encrypting_key": { "encrypted_key": "244YHfO_W7RMpQW81UjQrZcq5LSyqiPv" }, "encrypting_content": { "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM" }, "ciphertext": "qtPIMMaOBRgASL10dNQhOa7Gqrk7Eal1vwht7R4TT1uq-arsVCPaIeFwQfzrSS6oEUWbBtxEasE0vC6r7sphyVziMCVJEuRJyoAHFSP3eqQPb4Ic1SDSqyXjw_L3svybhHYUGyQuTmUQEDjgjJfBOifwHIsDsRPeBz1NomqeifVPq5GTCWFo5k_MNIQURR2Wj0AHC2k7JZfu2iWjUHLF8ExFZLZ4nlmsvJu_mvifMYiikfNfsZAudISOa6O73yPZtL04k_1FI7WDfrb2w7OqKLWDXzlpcxohPVOLQwpA3mFNRKdY-bQz4Z4KX9lfz1cne31N4-8BKmojpw-OdQjKdLOGkC445Fb_K1tlDQXw2sBF", "tag": "e2m0Vm7JvjK2VpCKXS-kyg" }, "output": { "json": { "recipients": [ { "encrypted_key": "244YHfO_W7RMpQW81UjQrZcq5LSyqiPv" } ], "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM" }, "iv": "YihBoVOGsR1l7jCD", "ciphertext": "qtPIMMaOBRgASL10dNQhOa7Gqrk7Eal1vwht7R4TT1uq-arsVCPaIeFwQfzrSS6oEUWbBtxEasE0vC6r7sphyVziMCVJEuRJyoAHFSP3eqQPb4Ic1SDSqyXjw_L3svybhHYUGyQuTmUQEDjgjJfBOifwHIsDsRPeBz1NomqeifVPq5GTCWFo5k_MNIQURR2Wj0AHC2k7JZfu2iWjUHLF8ExFZLZ4nlmsvJu_mvifMYiikfNfsZAudISOa6O73yPZtL04k_1FI7WDfrb2w7OqKLWDXzlpcxohPVOLQwpA3mFNRKdY-bQz4Z4KX9lfz1cne31N4-8BKmojpw-OdQjKdLOGkC445Fb_K1tlDQXw2sBF", "tag": "e2m0Vm7JvjK2VpCKXS-kyg" }, "json_flat": { "unprotected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM" }, "encrypted_key": "244YHfO_W7RMpQW81UjQrZcq5LSyqiPv", "iv": "YihBoVOGsR1l7jCD", "ciphertext": "qtPIMMaOBRgASL10dNQhOa7Gqrk7Eal1vwht7R4TT1uq-arsVCPaIeFwQfzrSS6oEUWbBtxEasE0vC6r7sphyVziMCVJEuRJyoAHFSP3eqQPb4Ic1SDSqyXjw_L3svybhHYUGyQuTmUQEDjgjJfBOifwHIsDsRPeBz1NomqeifVPq5GTCWFo5k_MNIQURR2Wj0AHC2k7JZfu2iWjUHLF8ExFZLZ4nlmsvJu_mvifMYiikfNfsZAudISOa6O73yPZtL04k_1FI7WDfrb2w7OqKLWDXzlpcxohPVOLQwpA3mFNRKdY-bQz4Z4KX9lfz1cne31N4-8BKmojpw-OdQjKdLOGkC445Fb_K1tlDQXw2sBF", "tag": "e2m0Vm7JvjK2VpCKXS-kyg" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_13.encrypting_to_multiple_recipients.json000066400000000000000000000160251452472117100306660ustar00rootroot00000000000000{ "title": "Encrypting to Multiple Recipients", "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": [ { "kty": "RSA", "kid": "frodo.baggins@hobbiton.example", "use": "enc", "n": "maxhbsmBtdQ3CNrKvprUE6n9lYcregDMLYNeTAWcLj8NnPU9XIYegTHVHQjxKDSHP2l-F5jS7sppG1wgdAqZyhnWvXhYNvcM7RfgKxqNx_xAHx6f3yy7s-M9PSNCwPC2lh6UAkR4I00EhV9lrypM9Pi4lBUop9t5fS9W5UNwaAllhrd-osQGPjIeI1deHTwx-ZTHu3C60Pu_LJIl6hKn9wbwaUmA4cR5Bd2pgbaY7ASgsjCUbtYJaNIHSoHXprUdJZKUMAzV0WOKPfA6OPI4oypBadjvMZ4ZAj3BnXaSYsEZhaueTXvZB4eZOAjIyh2e_VOIKVMsnDrJYAVotGlvMQ", "e": "AQAB", "d": "Kn9tgoHfiTVi8uPu5b9TnwyHwG5dK6RE0uFdlpCGnJN7ZEi963R7wybQ1PLAHmpIbNTztfrheoAniRV1NCIqXaW_qS461xiDTp4ntEPnqcKsyO5jMAji7-CL8vhpYYowNFvIesgMoVaPRYMYT9TW63hNM0aWs7USZ_hLg6Oe1mY0vHTI3FucjSM86Nff4oIENt43r2fspgEPGRrdE6fpLc9Oaq-qeP1GFULimrRdndm-P8q8kvN3KHlNAtEgrQAgTTgz80S-3VD0FgWfgnb1PNmiuPUxO8OpI9KDIfu_acc6fg14nsNaJqXe6RESvhGPH2afjHqSy_Fd2vpzj85bQQ", "p": "2DwQmZ43FoTnQ8IkUj3BmKRf5Eh2mizZA5xEJ2MinUE3sdTYKSLtaEoekX9vbBZuWxHdVhM6UnKCJ_2iNk8Z0ayLYHL0_G21aXf9-unynEpUsH7HHTklLpYAzOOx1ZgVljoxAdWNn3hiEFrjZLZGS7lOH-a3QQlDDQoJOJ2VFmU", "q": "te8LY4-W7IyaqH1ExujjMqkTAlTeRbv0VLQnfLY2xINnrWdwiQ93_VF099aP1ESeLja2nw-6iKIe-qT7mtCPozKfVtUYfz5HrJ_XY2kfexJINb9lhZHMv5p1skZpeIS-GPHCC6gRlKo1q-idn_qxyusfWv7WAxlSVfQfk8d6Et0", "dp": "UfYKcL_or492vVc0PzwLSplbg4L3-Z5wL48mwiswbpzOyIgd2xHTHQmjJpFAIZ8q-zf9RmgJXkDrFs9rkdxPtAsL1WYdeCT5c125Fkdg317JVRDo1inX7x2Kdh8ERCreW8_4zXItuTl_KiXZNU5lvMQjWbIw2eTx1lpsflo0rYU", "dq": "iEgcO-QfpepdH8FWd7mUFyrXdnOkXJBCogChY6YKuIHGc_p8Le9MbpFKESzEaLlN1Ehf3B6oGBl5Iz_ayUlZj2IoQZ82znoUrpa9fVYNot87ACfzIG7q9Mv7RiPAderZi03tkVXAdaBau_9vs5rS-7HMtxkVrxSUvJY14TkXlHE", "qi": "kC-lzZOqoFaZCr5l0tOVtREKoVqaAYhQiqIRGL-MzS4sCmRkxm5vZlXYx6RtE1n_AagjqajlkjieGlxTTThHD8Iga6foGBMaAr5uR1hGQpSc7Gl7CF1DZkBJMTQN6EshYzZfxW08mIO8M6Rzuh0beL6fG9mkDcIyPrBXx2bQ_mM" }, { "kty": "EC", "kid": "peregrin.took@tuckborough.example", "use": "enc", "crv": "P-384", "x": "YU4rRUzdmVqmRtWOs2OpDE_T5fsNIodcG8G5FWPrTPMyxpzsSOGaQLpe2FpxBmu2", "y": "A8-yxCHxkfBz3hKZfI1jUYMjUhsEveZ9THuwFjH2sCNdtksRJU7D5-SkgaFL1ETP", "d": "iTx2pk7wW-GqJkHcEkFQb2EFyYcO7RugmaW3mRrQVAOUiPommT0IdnYK2xDlZh-j" }, { "kty": "oct", "kid": "18ec08e1-bfa9-4d95-b205-2b4dd1d4321d", "use": "enc", "alg": "A256GCMKW", "k": "qC57l_uxcm7Nm3K-ct4GFjx8tM1U8CZ0NLBvdQstiS8" } ], "alg": [ "RSA1_5", "ECDH-ES+A256KW", "A256GCMKW" ], "enc": "A128CBC-H256" }, "generated": { "cek": "zXayeJ4gvm8NJr3IUInyokTUO-LbQNKEhe_zWlYbdpQ", "iv": "VgEIHY20EnzUtZFl2RpB1g" }, "encrypting_key": [ { "encrypted_key": "dYOD28kab0Vvf4ODgxVAJXgHcSZICSOp8M51zjwj4w6Y5G4XJQsNNIBiqyvUUAOcpL7S7-cFe7Pio7gV_Q06WmCSa-vhW6me4bWrBf7cHwEQJdXihidAYWVajJIaKMXMvFRMV6iDlRr076DFthg2_AV0_tSiV6xSEIFqt1xnYPpmP91tc5WJDOGb-wqjw0-b-S1laS11QVbuP78dQ7Fa0zAVzzjHX-xvyM2wxj_otxr9clN1LnZMbeYSrRicJK5xodvWgkpIdkMHo4LvdhRRvzoKzlic89jFWPlnBq_V4n5trGuExtp_-dbHcGlihqc_wGgho9fLMK8JOArYLcMDNQ", "header": { "alg": "RSA1_5", "kid": "frodo.baggins@hobbiton.example" } }, { "epk": { "kty": "EC", "crv": "P-384", "x": "Uzdvk3pi5wKCRc1izp5_r0OjeqT-I68i8g2b8mva8diRhsE2xAn2DtMRb25Ma2CX", "y": "VDrRyFJh-Kwd1EjAgmj5Eo-CTHAZ53MC7PjjpLioy3ylEjI1pOMbw91fzZ84pbfm", "d": "1DKHfTv-PiifVw2VBHM_ZiVcwOMxkOyANS_lQHJcrDxVY3jhVCvZPwMxJKIE793C" }, "encrypted_key": "ExInT0io9BqBMYF6-maw5tZlgoZXThD1zWKsHixJuw_elY4gSSId_w", "header": { "alg": "ECDH-ES+A256KW", "kid": "peregrin.took@tuckborough.example", "epk": { "kty": "EC", "crv": "P-384", "x": "Uzdvk3pi5wKCRc1izp5_r0OjeqT-I68i8g2b8mva8diRhsE2xAn2DtMRb25Ma2CX", "y": "VDrRyFJh-Kwd1EjAgmj5Eo-CTHAZ53MC7PjjpLioy3ylEjI1pOMbw91fzZ84pbfm" } } }, { "iv": "AvpeoPZ9Ncn9mkBn", "encrypted_key": "a7CclAejo_7JSuPB8zeagxXRam8dwCfmkt9-WyTpS1E", "tag": "59Nqh1LlYtVIhfD3pgRGvw", "header": { "alg": "A256GCMKW", "kid": "18ec08e1-bfa9-4d95-b205-2b4dd1d4321d", "tag": "59Nqh1LlYtVIhfD3pgRGvw", "iv": "AvpeoPZ9Ncn9mkBn" } } ], "encrypting_content": { "protected": { "enc": "A128CBC-HS256" }, "protected_b64u": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "unprotected": { "cty": "text/plain" }, "ciphertext": "ajm2Q-OpPXCr7-MHXicknb1lsxLdXxK_yLds0KuhJzfWK04SjdxQeSw2L9mu3a_k1C55kCQ_3xlkcVKC5yr__Is48VOoK0k63_QRM9tBURMFqLByJ8vOYQX0oJW4VUHJLmGhF-tVQWB7Kz8mr8zeE7txF0MSaP6ga7-siYxStR7_G07Thd1jh-zGT0wxM5g-VRORtq0K6AXpLlwEqRp7pkt2zRM0ZAXqSpe1O6FJ7FHLDyEFnD-zDIZukLpCbzhzMDLLw2-8I14FQrgi-iEuzHgIJFIJn2wh9Tj0cg_kOZy9BqMRZbmYXMY9YQjorZ_P_JYG3ARAIF3OjDNqpdYe-K_5Q5crGJSDNyij_ygEiItR5jssQVH2ofDQdLChtazE", "tag": "BESYyFN7T09KY7i8zKs5_g" }, "output": { "json": { "recipients": [ { "encrypted_key": "dYOD28kab0Vvf4ODgxVAJXgHcSZICSOp8M51zjwj4w6Y5G4XJQsNNIBiqyvUUAOcpL7S7-cFe7Pio7gV_Q06WmCSa-vhW6me4bWrBf7cHwEQJdXihidAYWVajJIaKMXMvFRMV6iDlRr076DFthg2_AV0_tSiV6xSEIFqt1xnYPpmP91tc5WJDOGb-wqjw0-b-S1laS11QVbuP78dQ7Fa0zAVzzjHX-xvyM2wxj_otxr9clN1LnZMbeYSrRicJK5xodvWgkpIdkMHo4LvdhRRvzoKzlic89jFWPlnBq_V4n5trGuExtp_-dbHcGlihqc_wGgho9fLMK8JOArYLcMDNQ", "header": { "alg": "RSA1_5", "kid": "frodo.baggins@hobbiton.example" } }, { "encrypted_key": "ExInT0io9BqBMYF6-maw5tZlgoZXThD1zWKsHixJuw_elY4gSSId_w", "header": { "alg": "ECDH-ES+A256KW", "kid": "peregrin.took@tuckborough.example", "epk": { "kty": "EC", "crv": "P-384", "x": "Uzdvk3pi5wKCRc1izp5_r0OjeqT-I68i8g2b8mva8diRhsE2xAn2DtMRb25Ma2CX", "y": "VDrRyFJh-Kwd1EjAgmj5Eo-CTHAZ53MC7PjjpLioy3ylEjI1pOMbw91fzZ84pbfm" } } }, { "encrypted_key": "a7CclAejo_7JSuPB8zeagxXRam8dwCfmkt9-WyTpS1E", "header": { "alg": "A256GCMKW", "kid": "18ec08e1-bfa9-4d95-b205-2b4dd1d4321d", "tag": "59Nqh1LlYtVIhfD3pgRGvw", "iv": "AvpeoPZ9Ncn9mkBn" } } ], "unprotected": { "cty": "text/plain" }, "protected": "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "iv": "VgEIHY20EnzUtZFl2RpB1g", "ciphertext": "ajm2Q-OpPXCr7-MHXicknb1lsxLdXxK_yLds0KuhJzfWK04SjdxQeSw2L9mu3a_k1C55kCQ_3xlkcVKC5yr__Is48VOoK0k63_QRM9tBURMFqLByJ8vOYQX0oJW4VUHJLmGhF-tVQWB7Kz8mr8zeE7txF0MSaP6ga7-siYxStR7_G07Thd1jh-zGT0wxM5g-VRORtq0K6AXpLlwEqRp7pkt2zRM0ZAXqSpe1O6FJ7FHLDyEFnD-zDIZukLpCbzhzMDLLw2-8I14FQrgi-iEuzHgIJFIJn2wh9Tj0cg_kOZy9BqMRZbmYXMY9YQjorZ_P_JYG3ARAIF3OjDNqpdYe-K_5Q5crGJSDNyij_ygEiItR5jssQVH2ofDQdLChtazE", "tag": "BESYyFN7T09KY7i8zKs5_g" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_2.key_encryption_using_rsa-oaep_with_aes-gcm.json000066400000000000000000000217601452472117100322470ustar00rootroot00000000000000{ "title": "Key Encryption using RSA-OAEP with AES-GCM", "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "RSA", "kid": "samwise.gamgee@hobbiton.example", "use": "enc", "n": "wbdxI55VaanZXPY29Lg5hdmv2XhvqAhoxUkanfzf2-5zVUxa6prHRrI4pP1AhoqJRlZfYtWWd5mmHRG2pAHIlh0ySJ9wi0BioZBl1XP2e-C-FyXJGcTy0HdKQWlrfhTm42EW7Vv04r4gfao6uxjLGwfpGrZLarohiWCPnkNrg71S2CuNZSQBIPGjXfkmIy2tl_VWgGnL22GplyXj5YlBLdxXp3XeStsqo571utNfoUTU8E4qdzJ3U1DItoVkPGsMwlmmnJiwA7sXRItBCivR4M5qnZtdw-7v4WuR4779ubDuJ5nalMv2S66-RPcnFAzWSKxtBDnFJJDGIUe7Tzizjg1nms0Xq_yPub_UOlWn0ec85FCft1hACpWG8schrOBeNqHBODFskYpUc2LC5JA2TaPF2dA67dg1TTsC_FupfQ2kNGcE1LgprxKHcVWYQb86B-HozjHZcqtauBzFNV5tbTuB-TpkcvJfNcFLlH3b8mb-H_ox35FjqBSAjLKyoeqfKTpVjvXhd09knwgJf6VKq6UC418_TOljMVfFTWXUxlnfhOOnzW6HSSzD1c9WrCuVzsUMv54szidQ9wf1cYWf3g5qFDxDQKis99gcDaiCAwM3yEBIzuNeeCa5dartHDb1xEB_HcHSeYbghbMjGfasvKn0aZRsnTyC0xhWBlsolZE", "e": "AQAB", "alg": "RSA-OAEP", "d": "n7fzJc3_WG59VEOBTkayzuSMM780OJQuZjN_KbH8lOZG25ZoA7T4Bxcc0xQn5oZE5uSCIwg91oCt0JvxPcpmqzaJZg1nirjcWZ-oBtVk7gCAWq-B3qhfF3izlbkosrzjHajIcY33HBhsy4_WerrXg4MDNE4HYojy68TcxT2LYQRxUOCf5TtJXvM8olexlSGtVnQnDRutxEUCwiewfmmrfveEogLx9EA-KMgAjTiISXxqIXQhWUQX1G7v_mV_Hr2YuImYcNcHkRvp9E7ook0876DhkO8v4UOZLwA1OlUX98mkoqwc58A_Y2lBYbVx1_s5lpPsEqbbH-nqIjh1fL0gdNfihLxnclWtW7pCztLnImZAyeCWAG7ZIfv-Rn9fLIv9jZ6r7r-MSH9sqbuziHN2grGjD_jfRluMHa0l84fFKl6bcqN1JWxPVhzNZo01yDF-1LiQnqUYSepPf6X3a2SOdkqBRiquE6EvLuSYIDpJq3jDIsgoL8Mo1LoomgiJxUwL_GWEOGu28gplyzm-9Q0U0nyhEf1uhSR8aJAQWAiFImWH5W_IQT9I7-yrindr_2fWQ_i1UgMsGzA7aOGzZfPljRy6z-tY_KuBG00-28S_aWvjyUc-Alp8AUyKjBZ-7CWH32fGWK48j1t-zomrwjL_mnhsPbGs0c9WsWgRzI-K8gE", "p": "7_2v3OQZzlPFcHyYfLABQ3XP85Es4hCdwCkbDeltaUXgVy9l9etKghvM4hRkOvbb01kYVuLFmxIkCDtpi-zLCYAdXKrAK3PtSbtzld_XZ9nlsYa_QZWpXB_IrtFjVfdKUdMz94pHUhFGFj7nr6NNxfpiHSHWFE1zD_AC3mY46J961Y2LRnreVwAGNw53p07Db8yD_92pDa97vqcZOdgtybH9q6uma-RFNhO1AoiJhYZj69hjmMRXx-x56HO9cnXNbmzNSCFCKnQmn4GQLmRj9sfbZRqL94bbtE4_e0Zrpo8RNo8vxRLqQNwIy85fc6BRgBJomt8QdQvIgPgWCv5HoQ", "q": "zqOHk1P6WN_rHuM7ZF1cXH0x6RuOHq67WuHiSknqQeefGBA9PWs6ZyKQCO-O6mKXtcgE8_Q_hA2kMRcKOcvHil1hqMCNSXlflM7WPRPZu2qCDcqssd_uMbP-DqYthH_EzwL9KnYoH7JQFxxmcv5An8oXUtTwk4knKjkIYGRuUwfQTus0w1NfjFAyxOOiAQ37ussIcE6C6ZSsM3n41UlbJ7TCqewzVJaPJN5cxjySPZPD3Vp01a9YgAD6a3IIaKJdIxJS1ImnfPevSJQBE79-EXe2kSwVgOzvt-gsmM29QQ8veHy4uAqca5dZzMs7hkkHtw1z0jHV90epQJJlXXnH8Q", "dp": "19oDkBh1AXelMIxQFm2zZTqUhAzCIr4xNIGEPNoDt1jK83_FJA-xnx5kA7-1erdHdms_Ef67HsONNv5A60JaR7w8LHnDiBGnjdaUmmuO8XAxQJ_ia5mxjxNjS6E2yD44USo2JmHvzeeNczq25elqbTPLhUpGo1IZuG72FZQ5gTjXoTXC2-xtCDEUZfaUNh4IeAipfLugbpe0JAFlFfrTDAMUFpC3iXjxqzbEanflwPvj6V9iDSgjj8SozSM0dLtxvu0LIeIQAeEgT_yXcrKGmpKdSO08kLBx8VUjkbv_3Pn20Gyu2YEuwpFlM_H1NikuxJNKFGmnAq9LcnwwT0jvoQ", "dq": "S6p59KrlmzGzaQYQM3o0XfHCGvfqHLYjCO557HYQf72O9kLMCfd_1VBEqeD-1jjwELKDjck8kOBl5UvohK1oDfSP1DleAy-cnmL29DqWmhgwM1ip0CCNmkmsmDSlqkUXDi6sAaZuntyukyflI-qSQ3C_BafPyFaKrt1fgdyEwYa08pESKwwWisy7KnmoUvaJ3SaHmohFS78TJ25cfc10wZ9hQNOrIChZlkiOdFCtxDqdmCqNacnhgE3bZQjGp3n83ODSz9zwJcSUvODlXBPc2AycH6Ci5yjbxt4Ppox_5pjm6xnQkiPgj01GpsUssMmBN7iHVsrE7N2iznBNCeOUIQ", "qi": "FZhClBMywVVjnuUud-05qd5CYU0dK79akAgy9oX6RX6I3IIIPckCciRrokxglZn-omAY5CnCe4KdrnjFOT5YUZE7G_Pg44XgCXaarLQf4hl80oPEf6-jJ5Iy6wPRx7G2e8qLxnh9cOdf-kRqgOS3F48Ucvw3ma5V6KGMwQqWFeV31XtZ8l5cVI-I3NzBS7qltpUVgz2Ju021eyc7IlqgzR98qKONl27DuEES0aK0WE97jnsyO27Yp88Wa2RiBrEocM89QZI1seJiGDizHRUP4UZxw9zsXww46wy0P6f9grnYp7t8LkyDDk8eoI4KX6SNMNVcyVS9IWjlq8EzqZEKIA" }, "alg": "RSA-OAEP", "enc": "A256GCM" }, "generated": { "cek": "mYMfsggkTAm0TbvtlFh2hyoXnbEzJQjMxmgLN3d8xXA", "iv": "-nBoKLH0YkLZPSI9" }, "encrypting_key": { "encrypted_key": "rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs" }, "encrypting_content": { "protected": { "alg": "RSA-OAEP", "kid": "samwise.gamgee@hobbiton.example", "enc": "A256GCM" }, "protected_b64u": "eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0", "ciphertext": "o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw", "tag": "UCGiqJxhBI3IFVdPalHHvA" }, "output": { "compact": "eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0.rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs.-nBoKLH0YkLZPSI9.o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw.UCGiqJxhBI3IFVdPalHHvA", "json": { "recipients": [ { "encrypted_key": "rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs" } ], "protected": "eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0", "iv": "-nBoKLH0YkLZPSI9", "ciphertext": "o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw", "tag": "UCGiqJxhBI3IFVdPalHHvA" }, "json_flat": { "protected": "eyJhbGciOiJSU0EtT0FFUCIsImtpZCI6InNhbXdpc2UuZ2FtZ2VlQGhvYmJpdG9uLmV4YW1wbGUiLCJlbmMiOiJBMjU2R0NNIn0", "encrypted_key": "rT99rwrBTbTI7IJM8fU3Eli7226HEB7IchCxNuh7lCiud48LxeolRdtFF4nzQibeYOl5S_PJsAXZwSXtDePz9hk-BbtsTBqC2UsPOdwjC9NhNupNNu9uHIVftDyucvI6hvALeZ6OGnhNV4v1zx2k7O1D89mAzfw-_kT3tkuorpDU-CpBENfIHX1Q58-Aad3FzMuo3Fn9buEP2yXakLXYa15BUXQsupM4A1GD4_H4Bd7V3u9h8Gkg8BpxKdUV9ScfJQTcYm6eJEBz3aSwIaK4T3-dwWpuBOhROQXBosJzS1asnuHtVMt2pKIIfux5BC6huIvmY7kzV7W7aIUrpYm_3H4zYvyMeq5pGqFmW2k8zpO878TRlZx7pZfPYDSXZyS0CfKKkMozT_qiCwZTSz4duYnt8hS4Z9sGthXn9uDqd6wycMagnQfOTs_lycTWmY-aqWVDKhjYNRf03NiwRtb5BE-tOdFwCASQj3uuAgPGrO2AWBe38UjQb0lvXn1SpyvYZ3WFc7WOJYaTa7A8DRn6MC6T-xDmMuxC0G7S2rscw5lQQU06MvZTlFOt0UvfuKBa03cxA_nIBIhLMjY2kOTxQMmpDPTr6Cbo8aKaOnx6ASE5Jx9paBpnNmOOKH35j_QlrQhDWUN6A2Gg8iFayJ69xDEdHAVCGRzN3woEI2ozDRs", "iv": "-nBoKLH0YkLZPSI9", "ciphertext": "o4k2cnGN8rSSw3IDo1YuySkqeS_t2m1GXklSgqBdpACm6UJuJowOHC5ytjqYgRL-I-soPlwqMUf4UgRWWeaOGNw6vGW-xyM01lTYxrXfVzIIaRdhYtEMRBvBWbEwP7ua1DRfvaOjgZv6Ifa3brcAM64d8p5lhhNcizPersuhw5f-pGYzseva-TUaL8iWnctc-sSwy7SQmRkfhDjwbz0fz6kFovEgj64X1I5s7E6GLp5fnbYGLa1QUiML7Cc2GxgvI7zqWo0YIEc7aCflLG1-8BboVWFdZKLK9vNoycrYHumwzKluLWEbSVmaPpOslY2n525DxDfWaVFUfKQxMF56vn4B9QMpWAbnypNimbM8zVOw", "tag": "UCGiqJxhBI3IFVdPalHHvA" } } } 5_3.key_wrap_using_pbes2-aes-keywrap_with-aes-cbc-hmac-sha2.json000066400000000000000000000107251452472117100341410ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jwe{ "title": "Key Wrap using PBES2-AES-KeyWrap with AES-CBC-HMAC-SHA2", "reproducible": true, "input": { "plaintext": "{\"keys\":[{\"kty\":\"oct\",\"kid\":\"77c7e2b8-6e13-45cf-8672-617b5b45243a\",\"use\":\"enc\",\"alg\":\"A128GCM\",\"k\":\"XctOhJAkA-pD9Lh7ZgW_2A\"},{\"kty\":\"oct\",\"kid\":\"81b20965-8332-43d9-a468-82160ad91ac8\",\"use\":\"enc\",\"alg\":\"A128KW\",\"k\":\"GZy6sIZ6wl9NJOKB-jnmVQ\"},{\"kty\":\"oct\",\"kid\":\"18ec08e1-bfa9-4d95-b205-2b4dd1d4321d\",\"use\":\"enc\",\"alg\":\"A256GCMKW\",\"k\":\"qC57l_uxcm7Nm3K-ct4GFjx8tM1U8CZ0NLBvdQstiS8\"}]}", "pwd": "entrap_o–peter_long–credit_tun", "alg": "PBES2-HS512+A256KW", "enc": "A128CBC-HS256" }, "generated": { "cek": "uwsjJXaBK407Qaf0_zpcpmr1Cs0CC50hIUEyGNEt3m0", "iv": "VBiCzVHNoLiR3F4V82uoTQ" }, "encrypting_key": { "salt": "8Q1SzinasR3xchYz6ZZcHA", "iteration_count": 8192, "encrypted_key": "d3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g" }, "encrypting_content": { "protected": { "alg": "PBES2-HS512+A256KW", "p2s": "8Q1SzinasR3xchYz6ZZcHA", "p2c": 8192, "cty": "jwk-set+json", "enc": "A128CBC-HS256" }, "protected_b64u":"eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "ciphertext": "23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p", "tag": "0HlwodAhOCILG5SQ2LQ9dg" }, "output": { "compact": "eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.d3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g.VBiCzVHNoLiR3F4V82uoTQ.23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p.0HlwodAhOCILG5SQ2LQ9dg", "json": { "recipients": [ { "encrypted_key": "d3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g" } ], "protected": "eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "iv": "VBiCzVHNoLiR3F4V82uoTQ", "ciphertext": "23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p", "tag": "0HlwodAhOCILG5SQ2LQ9dg" }, "json_flat": { "protected": "eyJhbGciOiJQQkVTMi1IUzUxMitBMjU2S1ciLCJwMnMiOiI4UTFTemluYXNSM3hjaFl6NlpaY0hBIiwicDJjIjo4MTkyLCJjdHkiOiJqd2stc2V0K2pzb24iLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0", "encrypted_key": "d3qNhUWfqheyPp4H8sjOWsDYajoej4c5Je6rlUtFPWdgtURtmeDV1g", "iv": "VBiCzVHNoLiR3F4V82uoTQ", "ciphertext": "23i-Tb1AV4n0WKVSSgcQrdg6GRqsUKxjruHXYsTHAJLZ2nsnGIX86vMXqIi6IRsfywCRFzLxEcZBRnTvG3nhzPk0GDD7FMyXhUHpDjEYCNA_XOmzg8yZR9oyjo6lTF6si4q9FZ2EhzgFQCLO_6h5EVg3vR75_hkBsnuoqoM3dwejXBtIodN84PeqMb6asmas_dpSsz7H10fC5ni9xIz424givB1YLldF6exVmL93R3fOoOJbmk2GBQZL_SEGllv2cQsBgeprARsaQ7Bq99tT80coH8ItBjgV08AtzXFFsx9qKvC982KLKdPQMTlVJKkqtV4Ru5LEVpBZXBnZrtViSOgyg6AiuwaS-rCrcD_ePOGSuxvgtrokAKYPqmXUeRdjFJwafkYEkiuDCV9vWGAi1DH2xTafhJwcmywIyzi4BqRpmdn_N-zl5tuJYyuvKhjKv6ihbsV_k1hJGPGAxJ6wUpmwC4PTQ2izEm0TuSE8oMKdTw8V3kobXZ77ulMwDs4p", "tag": "0HlwodAhOCILG5SQ2LQ9dg" } } } 5_4.key_agreement_with_key_wrapping_using_ecdh-es_and_aes-keywrap_with_aes-gcm.json000066400000000000000000000120441452472117100405070ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jwe{ "title": "Key Agreement with Key Wrapping using ECDH-ES and AES-KeyWrap with AES-GCM", "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "EC", "kid": "peregrin.took@tuckborough.example", "use": "enc", "crv": "P-384", "x": "YU4rRUzdmVqmRtWOs2OpDE_T5fsNIodcG8G5FWPrTPMyxpzsSOGaQLpe2FpxBmu2", "y": "A8-yxCHxkfBz3hKZfI1jUYMjUhsEveZ9THuwFjH2sCNdtksRJU7D5-SkgaFL1ETP", "d": "iTx2pk7wW-GqJkHcEkFQb2EFyYcO7RugmaW3mRrQVAOUiPommT0IdnYK2xDlZh-j" }, "alg": "ECDH-ES+A128KW", "enc": "A128GCM" }, "generated": { "cek": "Nou2ueKlP70ZXDbq9UrRwg", "iv": "mH-G2zVqgztUtnW_" }, "encrypting_key": { "epk": { "kty": "EC", "crv": "P-384", "x": "uBo4kHPw6kbjx5l0xowrd_oYzBmaz-GKFZu4xAFFkbYiWgutEK6iuEDsQ6wNdNg3", "y": "sp3p5SGhZVC2faXumI-e9JU2Mo8KpoYrFDr5yPNVtW4PgEwZOyQTA-JdaY8tb7E0", "d": "D5H4Y_5PSKZvhfVFbcCYJOtcGZygRgfZkpsBr59Icmmhe9sW6nkZ8WfwhinUfWJg" }, "encrypted_key": "0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2" }, "encrypting_content": { "protected": { "alg": "ECDH-ES+A128KW", "kid": "peregrin.took@tuckborough.example", "epk": { "kty": "EC", "crv": "P-384", "x": "uBo4kHPw6kbjx5l0xowrd_oYzBmaz-GKFZu4xAFFkbYiWgutEK6iuEDsQ6wNdNg3", "y": "sp3p5SGhZVC2faXumI-e9JU2Mo8KpoYrFDr5yPNVtW4PgEwZOyQTA-JdaY8tb7E0" }, "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0", "ciphertext": "tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ", "tag": "WuGzxmcreYjpHGJoa17EBg" }, "output": { "compact": "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0.0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2.mH-G2zVqgztUtnW_.tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ.WuGzxmcreYjpHGJoa17EBg", "json": { "recipients": [ { "encrypted_key": "0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2" } ], "protected": "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0", "iv": "mH-G2zVqgztUtnW_", "ciphertext": "tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ", "tag": "WuGzxmcreYjpHGJoa17EBg" }, "json_flat": { "protected": "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImtpZCI6InBlcmVncmluLnRvb2tAdHVja2Jvcm91Z2guZXhhbXBsZSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InVCbzRrSFB3Nmtiang1bDB4b3dyZF9vWXpCbWF6LUdLRlp1NHhBRkZrYllpV2d1dEVLNml1RURzUTZ3TmROZzMiLCJ5Ijoic3AzcDVTR2haVkMyZmFYdW1JLWU5SlUyTW84S3BvWXJGRHI1eVBOVnRXNFBnRXdaT3lRVEEtSmRhWTh0YjdFMCJ9LCJlbmMiOiJBMTI4R0NNIn0", "encrypted_key": "0DJjBXri_kBcC46IkU5_Jk9BqaQeHdv2", "iv": "mH-G2zVqgztUtnW_", "ciphertext": "tkZuOO9h95OgHJmkkrfLBisku8rGf6nzVxhRM3sVOhXgz5NJ76oID7lpnAi_cPWJRCjSpAaUZ5dOR3Spy7QuEkmKx8-3RCMhSYMzsXaEwDdXta9Mn5B7cCBoJKB0IgEnj_qfo1hIi-uEkUpOZ8aLTZGHfpl05jMwbKkTe2yK3mjF6SBAsgicQDVCkcY9BLluzx1RmC3ORXaM0JaHPB93YcdSDGgpgBWMVrNU1ErkjcMqMoT_wtCex3w03XdLkjXIuEr2hWgeP-nkUZTPU9EoGSPj6fAS-bSz87RCPrxZdj_iVyC6QWcqAu07WNhjzJEPc4jVntRJ6K53NgPQ5p99l3Z408OUqj4ioYezbS6vTPlQ", "tag": "WuGzxmcreYjpHGJoa17EBg" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_5.key_agreement_using_ecdh-es_with_aes-cbc-hmac-sha2.json000066400000000000000000000110141452472117100333410ustar00rootroot00000000000000{ "title": "Key Agreement using ECDH-ES with AES-CBC-HMAC-SHA2", "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "EC", "kid": "meriadoc.brandybuck@buckland.example", "use": "enc", "crv": "P-256", "x": "Ze2loSV3wrroKUN_4zhwGhCqo3Xhu1td4QjeQ5wIVR0", "y": "HlLtdXARY_f55A3fnzQbPcm6hgr34Mp8p-nuzQCE0Zw", "d": "r_kHyZ-a06rmxM3yESK84r1otSg-aQcVStkRhA-iCM8" }, "alg": "ECDH-ES", "enc": "A128CBC-HS256" }, "generated": { "iv": "yc9N8v5sYyv3iGQT926IUg" }, "encrypting_key": { "epk": { "kty": "EC", "crv": "P-256", "x": "mPUKT_bAWGHIhg0TpjjqVsP1rXWQu_vwVOHHtNkdYoA", "y": "8BQAsImGeAS46fyWw5MhYfGTT0IjBpFw2SS34Dv4Irs", "d": "AtH35vJsQ9SGjYfOsjUxYXQKrPH3FjZHmEtSKoSN8cM" }, "cek": "hzHdlfQIAEehb8Hrd_mFRhKsKLEzPfshfXs9l6areCc" }, "encrypting_content": { "protected": { "alg": "ECDH-ES", "kid": "meriadoc.brandybuck@buckland.example", "epk": { "kty": "EC", "crv": "P-256", "x": "mPUKT_bAWGHIhg0TpjjqVsP1rXWQu_vwVOHHtNkdYoA", "y": "8BQAsImGeAS46fyWw5MhYfGTT0IjBpFw2SS34Dv4Irs" }, "enc": "A128CBC-HS256" }, "protected_b64u": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ", "ciphertext": "BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg", "tag": "WCCkNa-x4BeB9hIDIfFuhg" }, "output": { "compact": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ..yc9N8v5sYyv3iGQT926IUg.BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg.WCCkNa-x4BeB9hIDIfFuhg", "json": { "protected": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ", "iv": "yc9N8v5sYyv3iGQT926IUg", "ciphertext": "BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg", "tag": "WCCkNa-x4BeB9hIDIfFuhg" }, "json_flat": { "protected": "eyJhbGciOiJFQ0RILUVTIiwia2lkIjoibWVyaWFkb2MuYnJhbmR5YnVja0BidWNrbGFuZC5leGFtcGxlIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoibVBVS1RfYkFXR0hJaGcwVHBqanFWc1AxclhXUXVfdndWT0hIdE5rZFlvQSIsInkiOiI4QlFBc0ltR2VBUzQ2ZnlXdzVNaFlmR1RUMElqQnBGdzJTUzM0RHY0SXJzIn0sImVuYyI6IkExMjhDQkMtSFMyNTYifQ", "iv": "yc9N8v5sYyv3iGQT926IUg", "ciphertext": "BoDlwPnTypYq-ivjmQvAYJLb5Q6l-F3LIgQomlz87yW4OPKbWE1zSTEFjDfhU9IPIOSA9Bml4m7iDFwA-1ZXvHteLDtw4R1XRGMEsDIqAYtskTTmzmzNa-_q4F_evAPUmwlO-ZG45Mnq4uhM1fm_D9rBtWolqZSF3xGNNkpOMQKF1Cl8i8wjzRli7-IXgyirlKQsbhhqRzkv8IcY6aHl24j03C-AR2le1r7URUhArM79BY8soZU0lzwI-sD5PZ3l4NDCCei9XkoIAfsXJWmySPoeRb2Ni5UZL4mYpvKDiwmyzGd65KqVw7MsFfI_K767G9C9Azp73gKZD0DyUn1mn0WW5LmyX_yJ-3AROq8p1WZBfG-ZyJ6195_JGG2m9Csg", "tag": "WCCkNa-x4BeB9hIDIfFuhg" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_6.direct_encryption_using_aes-gcm.json000066400000000000000000000047031452472117100301110ustar00rootroot00000000000000{ "title": "Direction Encryption using AES-GCM", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "77c7e2b8-6e13-45cf-8672-617b5b45243a", "use": "enc", "alg": "A128GCM", "k": "XctOhJAkA-pD9Lh7ZgW_2A" }, "alg": "dir", "enc": "A128GCM" }, "generated": { "iv": "refa467QzzKx6QAB" }, "encrypting_content": { "protected": { "alg": "dir", "kid": "77c7e2b8-6e13-45cf-8672-617b5b45243a", "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0", "ciphertext": "JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp", "tag": "vbb32Xvllea2OtmHAdccRQ" }, "output": { "compact": "eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0..refa467QzzKx6QAB.JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp.vbb32Xvllea2OtmHAdccRQ", "json_flat": { "protected": "eyJhbGciOiJkaXIiLCJraWQiOiI3N2M3ZTJiOC02ZTEzLTQ1Y2YtODY3Mi02MTdiNWI0NTI0M2EiLCJlbmMiOiJBMTI4R0NNIn0", "iv": "refa467QzzKx6QAB", "ciphertext": "JW_i_f52hww_ELQPGaYyeAB6HYGcR559l9TYnSovc23XJoBcW29rHP8yZOZG7YhLpT1bjFuvZPjQS-m0IFtVcXkZXdH_lr_FrdYt9HRUYkshtrMmIUAyGmUnd9zMDB2n0cRDIHAzFVeJUDxkUwVAE7_YGRPdcqMyiBoCO-FBdE-Nceb4h3-FtBP-c_BIwCPTjb9o0SbdcdREEMJMyZBH8ySWMVi1gPD9yxi-aQpGbSv_F9N4IZAxscj5g-NJsUPbjk29-s7LJAGb15wEBtXphVCgyy53CoIKLHHeJHXex45Uz9aKZSRSInZI-wjsY0yu3cT4_aQ3i1o-tiE-F8Ios61EKgyIQ4CWao8PFMj8TTnp", "tag": "vbb32Xvllea2OtmHAdccRQ" } } } 5_7.key_wrap_using_aes-gcm_keywrap_with_aes-cbc-hmac-sha2.json000066400000000000000000000100711452472117100340360ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jwe{ "title": "Key Wrap using AES-GCM KeyWrap with AES-CBC-HMAC-SHA2", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "18ec08e1-bfa9-4d95-b205-2b4dd1d4321d", "use": "enc", "alg": "A256GCMKW", "k": "qC57l_uxcm7Nm3K-ct4GFjx8tM1U8CZ0NLBvdQstiS8" }, "alg": "A256GCMKW", "enc": "A128CBC-HS256" }, "generated": { "cek": "UWxARpat23nL9ReIj4WG3D1ee9I4r-Mv5QLuFXdy_rE", "iv": "gz6NjyEFNm_vm8Gj6FwoFQ" }, "encrypting_key": { "iv": "KkYT0GX_2jHlfqN_", "encrypted_key": "lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok", "tag": "kfPduVQ3T3H6vnewt--ksw" }, "encrypting_content": { "protected": { "alg": "A256GCMKW", "kid": "18ec08e1-bfa9-4d95-b205-2b4dd1d4321d", "tag": "kfPduVQ3T3H6vnewt--ksw", "iv": "KkYT0GX_2jHlfqN_", "enc": "A128CBC-HS256" }, "protected_b64u": "eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9", "ciphertext": "Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU", "tag": "DKW7jrb4WaRSNfbXVPlT5g" }, "output": { "compact": "eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9.lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok.gz6NjyEFNm_vm8Gj6FwoFQ.Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU.DKW7jrb4WaRSNfbXVPlT5g", "json": { "recipients": [ { "encrypted_key": "lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok" } ], "protected": "eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9", "iv": "gz6NjyEFNm_vm8Gj6FwoFQ", "ciphertext": "Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU", "tag": "DKW7jrb4WaRSNfbXVPlT5g" }, "json_flat": { "protected": "eyJhbGciOiJBMjU2R0NNS1ciLCJraWQiOiIxOGVjMDhlMS1iZmE5LTRkOTUtYjIwNS0yYjRkZDFkNDMyMWQiLCJ0YWciOiJrZlBkdVZRM1QzSDZ2bmV3dC0ta3N3IiwiaXYiOiJLa1lUMEdYXzJqSGxmcU5fIiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9", "encrypted_key": "lJf3HbOApxMEBkCMOoTnnABxs_CvTWUmZQ2ElLvYNok", "iv": "gz6NjyEFNm_vm8Gj6FwoFQ", "ciphertext": "Jf5p9-ZhJlJy_IQ_byKFmI0Ro7w7G1QiaZpI8OaiVgD8EqoDZHyFKFBupS8iaEeVIgMqWmsuJKuoVgzR3YfzoMd3GxEm3VxNhzWyWtZKX0gxKdy6HgLvqoGNbZCzLjqcpDiF8q2_62EVAbr2uSc2oaxFmFuIQHLcqAHxy51449xkjZ7ewzZaGV3eFqhpco8o4DijXaG5_7kp3h2cajRfDgymuxUbWgLqaeNQaJtvJmSMFuEOSAzw9Hdeb6yhdTynCRmu-kqtO5Dec4lT2OMZKpnxc_F1_4yDJFcqb5CiDSmA-psB2k0JtjxAj4UPI61oONK7zzFIu4gBfjJCndsZfdvG7h8wGjV98QhrKEnR7xKZ3KCr0_qR1B-gxpNk3xWU", "tag": "DKW7jrb4WaRSNfbXVPlT5g" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_8.key_wrap_using_aes-keywrap_with_aes-gcm.json000066400000000000000000000065721452472117100315610ustar00rootroot00000000000000{ "title": "Key Wrap using AES-KeyWrap with AES-GCM", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "use": "enc", "alg": "A128KW", "k": "GZy6sIZ6wl9NJOKB-jnmVQ" }, "alg": "A128KW", "enc": "A128GCM" }, "generated": { "cek": "aY5_Ghmk9KxWPBLu_glx1w", "iv": "Qx0pmsDa8KnJc9Jo" }, "encrypting_key": { "encrypted_key": "CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx" }, "encrypting_content": { "protected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM" }, "protected_b64u": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "ciphertext": "AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF", "tag": "ER7MWJZ1FBI_NKvn7Zb1Lw" }, "output": { "compact": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0.CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx.Qx0pmsDa8KnJc9Jo.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF.ER7MWJZ1FBI_NKvn7Zb1Lw", "json": { "recipients": [ { "encrypted_key": "CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx" } ], "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "iv": "Qx0pmsDa8KnJc9Jo", "ciphertext": "AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF", "tag": "ER7MWJZ1FBI_NKvn7Zb1Lw" }, "json_flat": { "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIn0", "encrypted_key": "CBI6oDw8MydIx1IBntf_lQcw2MmJKIQx", "iv": "Qx0pmsDa8KnJc9Jo", "ciphertext": "AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZF", "tag": "ER7MWJZ1FBI_NKvn7Zb1Lw" } } } rhonabwy-1.1.13/test/cookbook-master/jwe/5_9.compressed_content.json000066400000000000000000000062411452472117100254640ustar00rootroot00000000000000{ "title": "Compressed Content", "reproducible": true, "input": { "plaintext": "You can trust us to stick with you through thick and thin–to the bitter end. And you can trust us to keep any secret of yours–closer than you keep it yourself. But you cannot trust us to let you face trouble alone, and go off without a word. We are your friends, Frodo.", "key": { "kty": "oct", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "use": "enc", "alg": "A128KW", "k": "GZy6sIZ6wl9NJOKB-jnmVQ" }, "alg": "A128KW", "enc": "A128GCM", "zip": "DEF" }, "generated": { "plaintext_c": "bY_BDcIwDEVX-QNU3QEOrIA4pqlDokYxchxVvbEDGzIJbioOSJwc-f___HPjBu8KVFpVtAplVE1-wZo0YjNZo3C7R5v72pV5f5X382VWjYQpqZKAyjziZOr2B7kQPSy6oZIXUnDYbVKN4jNXi2u0yB7t1qSHTjmMODf9QgvrDzfTIQXnyQRuUya4zIWG3vTOdir0v7BRHFYWq3k1k1A_gSDJqtcBF-GZxw8", "cek": "hC-MpLZSuwWv8sexS6ydfw", "iv": "p9pUq6XHY0jfEZIl" }, "encrypting_key": { "encrypted_key": "5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi" }, "encrypting_content": { "protected": { "alg": "A128KW", "kid": "81b20965-8332-43d9-a468-82160ad91ac8", "enc": "A128GCM", "zip": "DEF" }, "protected_b64u": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0", "ciphertext": "HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw", "tag": "VILuUwuIxaLVmh5X-T7kmA" }, "output": { "compact": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0.5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi.p9pUq6XHY0jfEZIl.HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw.VILuUwuIxaLVmh5X-T7kmA", "json": { "recipients": [ { "encrypted_key": "5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi" } ], "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0", "iv": "p9pUq6XHY0jfEZIl", "ciphertext": "HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw", "tag": "VILuUwuIxaLVmh5X-T7kmA" }, "json_flat": { "protected": "eyJhbGciOiJBMTI4S1ciLCJraWQiOiI4MWIyMDk2NS04MzMyLTQzZDktYTQ2OC04MjE2MGFkOTFhYzgiLCJlbmMiOiJBMTI4R0NNIiwiemlwIjoiREVGIn0", "encrypted_key": "5vUT2WOtQxKWcekM_IzVQwkGgzlFDwPi", "iv": "p9pUq6XHY0jfEZIl", "ciphertext": "HbDtOsdai1oYziSx25KEeTxmwnh8L8jKMFNc1k3zmMI6VB8hry57tDZ61jXyezSPt0fdLVfe6Jf5y5-JaCap_JQBcb5opbmT60uWGml8blyiMQmOn9J--XhhlYg0m-BHaqfDO5iTOWxPxFMUedx7WCy8mxgDHj0aBMG6152PsM-w5E_o2B3jDbrYBKhpYA7qi3AyijnCJ7BP9rr3U8kxExCpG3mK420TjOw", "tag": "VILuUwuIxaLVmh5X-T7kmA" } } } rhonabwy-1.1.13/test/cookbook-master/jwk/000077500000000000000000000000001452472117100203035ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jwk/3_1.ec_public_key.json000066400000000000000000000004451452472117100243570ustar00rootroot00000000000000{ "kty": "EC", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "crv": "P-521", "x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt", "y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1" } rhonabwy-1.1.13/test/cookbook-master/jwk/3_2.ec_private_key.json000066400000000000000000000006101452472117100245460ustar00rootroot00000000000000{ "kty": "EC", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "crv": "P-521", "x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt", "y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1", "d": "AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt" } rhonabwy-1.1.13/test/cookbook-master/jwk/3_3.rsa_public_key.json000066400000000000000000000006761452472117100245650ustar00rootroot00000000000000{ "kty": "RSA", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw", "e": "AQAB" } rhonabwy-1.1.13/test/cookbook-master/jwk/3_4.rsa_private_key.json000066400000000000000000000032601452472117100247520ustar00rootroot00000000000000{ "kty": "RSA", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw", "e": "AQAB", "d": "bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ", "p": "3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k", "q": "uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc", "dp": "B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik", "dq": "CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8", "qi": "3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4" } rhonabwy-1.1.13/test/cookbook-master/jwk/3_5.symmetric_key_mac_computation.json000066400000000000000000000002341452472117100277100ustar00rootroot00000000000000{ "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" } rhonabwy-1.1.13/test/cookbook-master/jwk/3_6.symmetric_key_encryption.json000066400000000000000000000002361452472117100267230ustar00rootroot00000000000000{ "kty": "oct", "kid": "1e571774-2e08-40da-8308-e8d68773842d", "use": "enc", "alg": "A256GCM", "k": "AAPapAv4LbFbiVawEjagUBluYqN5rhna-8nuldDvOx8" } rhonabwy-1.1.13/test/cookbook-master/jws/000077500000000000000000000000001452472117100203135ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/jws/4_1.rsa_v15_signature.json000066400000000000000000000120071452472117100251310ustar00rootroot00000000000000{ "title": "RSA v1.5 Signature", "reproducible": true, "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "RSA", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw", "e": "AQAB", "d": "bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ", "p": "3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k", "q": "uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc", "dp": "B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik", "dq": "CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8", "qi": "3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4" }, "alg": "RS256" }, "signing": { "protected": { "alg": "RS256", "kid": "bilbo.baggins@hobbiton.example" }, "protected_b64u": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "sig-input": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg" }, "output": { "compact": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg", "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "protected": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "MRjdkly7_-oTPTS3AXP41iQIGKa80A0ZmTuV5MEaHoxnW2e5CZ5NlKtainoFmKZopdHM1O2U4mwzJdQx996ivp83xuglII7PNDi84wnB-BDkoBwA78185hX-Es4JIwmDLJK3lfWRa-XtL0RnltuYv746iYTh_qHRD68BNt1uSNCrUCTJDt5aAE6x8wW1Kt9eRo4QPocSadnHXFxnt8Is9UzpERV0ePPQdLuW3IS_de3xyIrDaLGdjluPxUAhb6L2aXic1U12podGU0KLUQSE_oI-ZnmKJ3F4uOZDnd6QZWJushZ41Axf_fcIe8u9ipH84ogoree7vjbU5y18kDquDg" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_2.rsa-pss_signature.json000066400000000000000000000117561452472117100252540ustar00rootroot00000000000000{ "title": "RSA-PSS Signature", "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "RSA", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw", "e": "AQAB", "d": "bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ", "p": "3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k", "q": "uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc", "dp": "B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik", "dq": "CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8", "qi": "3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4" }, "alg": "PS384" }, "signing": { "protected": { "alg": "PS384", "kid": "bilbo.baggins@hobbiton.example" }, "protected_b64u": "eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "sig-input": "eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw" }, "output": { "compact": "eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw", "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "protected": "eyJhbGciOiJQUzM4NCIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "cu22eBqkYDKgIlTpzDXGvaFfz6WGoz7fUDcfT0kkOy42miAh2qyBzk1xEsnk2IpN6-tPid6VrklHkqsGqDqHCdP6O8TTB5dDDItllVo6_1OLPpcbUrhiUSMxbbXUvdvWXzg-UD8biiReQFlfz28zGWVsdiNAUf8ZnyPEgVFn442ZdNqiVJRmBqrYRXe8P_ijQ7p8Vdz0TTrxUeT3lm8d9shnr2lfJT8ImUjvAA2Xez2Mlp8cBE5awDzT0qI0n6uiP1aCN_2_jLAeQTlqRHtfa64QQSUmFAAjVKPbByi7xho0uTOcbH510a6GYmJUAfmWjwZ6oD4ifKo8DYM-X72Eaw" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_3.ecdsa_signature.json000066400000000000000000000060341452472117100247350ustar00rootroot00000000000000{ "title": "ECDSA Signature", "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "EC", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "crv": "P-521", "x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt", "y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1", "d": "AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt" }, "alg": "ES512" }, "signing": { "protected": { "alg": "ES512", "kid": "bilbo.baggins@hobbiton.example" }, "protected_b64u": "eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "sig-input": "eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2" }, "output": { "compact": "eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2", "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "protected": "eyJhbGciOiJFUzUxMiIsImtpZCI6ImJpbGJvLmJhZ2dpbnNAaG9iYml0b24uZXhhbXBsZSJ9", "signature": "AE_R_YZCChjn4791jSQCrdPZCNYqHXCTZH0-JZGYNlaAjP2kqaluUIIUnC9qvbu9Plon7KRTzoNEuT4Va2cmL1eJAQy3mtPBu_u_sDDyYjnAMDxXPn7XrT0lw-kvAD890jl8e2puQens_IEKBpHABlsbEPX6sFY8OcGDqoRuBomu9xQ2" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_4.hmac-sha2_integrity_protection.json000066400000000000000000000045511452472117100277070ustar00rootroot00000000000000{ "title": "HMAC-SHA2 Integrity Protection", "reproducible": true, "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" }, "alg": "HS256" }, "signing": { "protected": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "protected_b64u": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "sig-input": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" }, "output": { "compact": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4.s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0", "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_5.signature_with_detached_content.json000066400000000000000000000032431452472117100302050ustar00rootroot00000000000000{ "title": "Signature with Detached Content", "reproducible": true, "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" }, "alg": "HS256" }, "signing": { "protected": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "protected_b64u": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "sig-input": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" }, "output": { "compact": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9..s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0", "json": { "signatures": [ { "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } ] }, "json_flat": { "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_6.protecting_specific_header_fields.json000066400000000000000000000037261452472117100304660ustar00rootroot00000000000000{ "title": "Protecting Specific Header Fields", "reproducible": true, "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" }, "alg": "HS256" }, "signing": { "protected": { "alg": "HS256" }, "protected_b64u": "eyJhbGciOiJIUzI1NiJ9", "unprotected": { "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "sig-input": "eyJhbGciOiJIUzI1NiJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20" }, "output": { "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJIUzI1NiJ9", "header": { "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "signature": "bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "protected": "eyJhbGciOiJIUzI1NiJ9", "header": { "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "signature": "bWUSVaxorn7bEF1djytBd0kHv70Ly5pvbomzMWSOr20" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_7.protecting_content_only.json000066400000000000000000000035131452472117100265510ustar00rootroot00000000000000{ "title": "Protecting Content Only", "reproducible": true, "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": { "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" }, "alg": "HS256" }, "signing": { "unprotected": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "sig-input": ".SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk" }, "output": { "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "header": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "signature": "xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk" } ] }, "json_flat": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "header": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "signature": "xuLifqLGiblpv9zBpuZczWhNj1gARaLV3UxvxhJxZuk" } } } rhonabwy-1.1.13/test/cookbook-master/jws/4_8.multiple_signatures.json000066400000000000000000000160211452472117100256760ustar00rootroot00000000000000{ "title": "Multiple Signatures", "input": { "payload": "It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don't keep your feet, there’s no knowing where you might be swept off to.", "key": [ { "kty": "RSA", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "n": "n4EPtAOCc9AlkeQHPzHStgAbgs7bTZLwUBZdR8_KuKPEHLd4rHVTeT-O-XV2jRojdNhxJWTDvNd7nqQ0VEiZQHz_AJmSCpMaJMRBSFKrKb2wqVwGU_NsYOYL-QtiWN2lbzcEe6XC0dApr5ydQLrHqkHHig3RBordaZ6Aj-oBHqFEHYpPe7Tpe-OfVfHd1E6cS6M1FZcD1NNLYD5lFHpPI9bTwJlsde3uhGqC0ZCuEHg8lhzwOHrtIQbS0FVbb9k3-tVTU4fg_3L_vniUFAKwuCLqKnS2BYwdq_mzSnbLY7h_qixoR7jig3__kRhuaxwUkRz5iaiQkqgc5gHdrNP5zw", "e": "AQAB", "d": "bWUC9B-EFRIo8kpGfh0ZuyGPvMNKvYWNtB_ikiH9k20eT-O1q_I78eiZkpXxXQ0UTEs2LsNRS-8uJbvQ-A1irkwMSMkK1J3XTGgdrhCku9gRldY7sNA_AKZGh-Q661_42rINLRCe8W-nZ34ui_qOfkLnK9QWDDqpaIsA-bMwWWSDFu2MUBYwkHTMEzLYGqOe04noqeq1hExBTHBOBdkMXiuFhUq1BU6l-DqEiWxqg82sXt2h-LMnT3046AOYJoRioz75tSUQfGCshWTBnP5uDjd18kKhyv07lhfSJdrPdM5Plyl21hsFf4L_mHCuoFau7gdsPfHPxxjVOcOpBrQzwQ", "p": "3Slxg_DwTXJcb6095RoXygQCAZ5RnAvZlno1yhHtnUex_fp7AZ_9nRaO7HX_-SFfGQeutao2TDjDAWU4Vupk8rw9JR0AzZ0N2fvuIAmr_WCsmGpeNqQnev1T7IyEsnh8UMt-n5CafhkikzhEsrmndH6LxOrvRJlsPp6Zv8bUq0k", "q": "uKE2dh-cTf6ERF4k4e_jy78GfPYUIaUyoSSJuBzp3Cubk3OCqs6grT8bR_cu0Dm1MZwWmtdqDyI95HrUeq3MP15vMMON8lHTeZu2lmKvwqW7anV5UzhM1iZ7z4yMkuUwFWoBvyY898EXvRD-hdqRxHlSqAZ192zB3pVFJ0s7pFc", "dp": "B8PVvXkvJrj2L-GYQ7v3y9r6Kw5g9SahXBwsWUzp19TVlgI-YV85q1NIb1rxQtD-IsXXR3-TanevuRPRt5OBOdiMGQp8pbt26gljYfKU_E9xn-RULHz0-ed9E9gXLKD4VGngpz-PfQ_q29pk5xWHoJp009Qf1HvChixRX59ehik", "dq": "CLDmDGduhylc9o7r84rEUVn7pzQ6PF83Y-iBZx5NT-TpnOZKF1pErAMVeKzFEl41DlHHqqBLSM0W1sOFbwTxYWZDm6sI6og5iTbwQGIC3gnJKbi_7k_vJgGHwHxgPaX2PnvP-zyEkDERuf-ry4c_Z11Cq9AqC2yeL6kdKT1cYF8", "qi": "3PiqvXQN0zwMeE-sBvZgi289XP9XCQF3VWqPzMKnIgQp7_Tugo6-NZBKCQsMf3HaEGBjTVJs_jcK8-TRXvaKe-7ZMaQj8VfBdYkssbu0NKDDhjJ-GtiseaDVWt7dcH0cfwxgFUHpQh7FoCrjFJ6h6ZEpMF6xmujs4qMpPz8aaI4" }, { "kty": "EC", "kid": "bilbo.baggins@hobbiton.example", "use": "sig", "crv": "P-521", "x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt", "y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1", "d": "AAhRON2r9cqXX1hg-RoI6R1tX5p2rUAYdmpHZoC1XNM56KtscrX6zbKipQrCW9CGZH3T4ubpnoTKLDYJ_fF3_rJt" }, { "kty": "oct", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037", "use": "sig", "alg": "HS256", "k": "hJtXIZ2uSN5kbQfbtTNWbpdmhkV8FJG-Onbc6mxCcYg" } ], "alg": [ "RS256", "ES512", "HS256" ] }, "signing": [ { "protected": { "alg": "RS256" }, "protected_b64u": "eyJhbGciOiJSUzI1NiJ9", "unprotected": { "kid": "bilbo.baggins@hobbiton.example" }, "sig-input": "eyJhbGciOiJSUzI1NiJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "MIsjqtVlOpa71KE-Mss8_Nq2YH4FGhiocsqrgi5NvyG53uoimic1tcMdSg-qptrzZc7CG6Svw2Y13TDIqHzTUrL_lR2ZFcryNFiHkSw129EghGpwkpxaTn_THJTCglNbADko1MZBCdwzJxwqZc-1RlpO2HibUYyXSwO97BSe0_evZKdjvvKSgsIqjytKSeAMbhMBdMma622_BG5t4sdbuCHtFjp9iJmkio47AIwqkZV1aIZsv33uPUqBBCXbYoQJwt7mxPftHmNlGoOSMxR_3thmXTCm4US-xiNOyhbm8afKK64jU6_TPtQHiJeQJxz9G3Tx-083B745_AfYOnlC9w", "json": { "protected": "eyJhbGciOiJSUzI1NiJ9", "header": { "kid": "bilbo.baggins@hobbiton.example" }, "signature": "MIsjqtVlOpa71KE-Mss8_Nq2YH4FGhiocsqrgi5NvyG53uoimic1tcMdSg-qptrzZc7CG6Svw2Y13TDIqHzTUrL_lR2ZFcryNFiHkSw129EghGpwkpxaTn_THJTCglNbADko1MZBCdwzJxwqZc-1RlpO2HibUYyXSwO97BSe0_evZKdjvvKSgsIqjytKSeAMbhMBdMma622_BG5t4sdbuCHtFjp9iJmkio47AIwqkZV1aIZsv33uPUqBBCXbYoQJwt7mxPftHmNlGoOSMxR_3thmXTCm4US-xiNOyhbm8afKK64jU6_TPtQHiJeQJxz9G3Tx-083B745_AfYOnlC9w" } }, { "unprotected": { "alg": "ES512", "kid": "bilbo.baggins@hobbiton.example" }, "sig-input": ".SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "ARcVLnaJJaUWG8fG-8t5BREVAuTY8n8YHjwDO1muhcdCoFZFFjfISu0Cdkn9Ybdlmi54ho0x924DUz8sK7ZXkhc7AFM8ObLfTvNCrqcI3Jkl2U5IX3utNhODH6v7xgy1Qahsn0fyb4zSAkje8bAWz4vIfj5pCMYxxm4fgV3q7ZYhm5eD", "json": { "header": { "alg": "ES512", "kid": "bilbo.baggins@hobbiton.example" }, "signature": "ARcVLnaJJaUWG8fG-8t5BREVAuTY8n8YHjwDO1muhcdCoFZFFjfISu0Cdkn9Ybdlmi54ho0x924DUz8sK7ZXkhc7AFM8ObLfTvNCrqcI3Jkl2U5IX3utNhODH6v7xgy1Qahsn0fyb4zSAkje8bAWz4vIfj5pCMYxxm4fgV3q7ZYhm5eD" } }, { "protected": { "alg": "HS256", "kid": "018c0ae5-4d9b-471b-bfd6-eef314bc7037" }, "protected_b64u": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "sig-input": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9.SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "sig": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0", "json": { "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } } ], "output": { "json": { "payload": "SXTigJlzIGEgZGFuZ2Vyb3VzIGJ1c2luZXNzLCBGcm9kbywgZ29pbmcgb3V0IHlvdXIgZG9vci4gWW91IHN0ZXAgb250byB0aGUgcm9hZCwgYW5kIGlmIHlvdSBkb24ndCBrZWVwIHlvdXIgZmVldCwgdGhlcmXigJlzIG5vIGtub3dpbmcgd2hlcmUgeW91IG1pZ2h0IGJlIHN3ZXB0IG9mZiB0by4", "signatures": [ { "protected": "eyJhbGciOiJSUzI1NiJ9", "header": { "kid": "bilbo.baggins@hobbiton.example" }, "signature": "MIsjqtVlOpa71KE-Mss8_Nq2YH4FGhiocsqrgi5NvyG53uoimic1tcMdSg-qptrzZc7CG6Svw2Y13TDIqHzTUrL_lR2ZFcryNFiHkSw129EghGpwkpxaTn_THJTCglNbADko1MZBCdwzJxwqZc-1RlpO2HibUYyXSwO97BSe0_evZKdjvvKSgsIqjytKSeAMbhMBdMma622_BG5t4sdbuCHtFjp9iJmkio47AIwqkZV1aIZsv33uPUqBBCXbYoQJwt7mxPftHmNlGoOSMxR_3thmXTCm4US-xiNOyhbm8afKK64jU6_TPtQHiJeQJxz9G3Tx-083B745_AfYOnlC9w" }, { "header": { "alg": "ES512", "kid": "bilbo.baggins@hobbiton.example" }, "signature": "ARcVLnaJJaUWG8fG-8t5BREVAuTY8n8YHjwDO1muhcdCoFZFFjfISu0Cdkn9Ybdlmi54ho0x924DUz8sK7ZXkhc7AFM8ObLfTvNCrqcI3Jkl2U5IX3utNhODH6v7xgy1Qahsn0fyb4zSAkje8bAWz4vIfj5pCMYxxm4fgV3q7ZYhm5eD" }, { "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjAxOGMwYWU1LTRkOWItNDcxYi1iZmQ2LWVlZjMxNGJjNzAzNyJ9", "signature": "s0h6KThzkfBBBkLspW1h84VsJZFTsPPqMDA7g1Md7p0" } ] } } } rhonabwy-1.1.13/test/cookbook-master/package.json000066400000000000000000000012711452472117100217770ustar00rootroot00000000000000{ "name": "jose-cookbook", "version": "1.0.0", "description": "Examples from \"Examples of Protecting Content using JavaScript Object Signing and Encryption (JOSE)\" in a machine-readable format", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "https://github.com/linuxwolf/cookbook.git" }, "keywords": [ "jose", "jose-cookbook", "jwe", "jws", "jwe", "jwa" ], "author": "Matthew A Miller ", "license": "public domain", "bugs": { "url": "https://github.com/linuxwolf/cookbook/issues" }, "homepage": "https://github.com/linuxwolf/cookbook" } rhonabwy-1.1.13/test/cookbook-master/rfc7797/000077500000000000000000000000001452472117100206205ustar00rootroot00000000000000rhonabwy-1.1.13/test/cookbook-master/rfc7797/4.2.hmac-sha2_b64_false.json000066400000000000000000000017471452472117100254160ustar00rootroot00000000000000{ "title": "'b64'=false JSON only", "reproducible": true, "input": { "payload": "$.02", "key": { "kty": "oct", "alg": "HS256", "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" }, "alg": "HS256" }, "signing": { "protected": { "alg": "HS256", "b64": false, "crit":["b64"] }, "protected_b64u": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9", "sig-input": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9.$.02", "sig": "GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs" }, "output": { "json": { "payload": "$.02", "signatures": [ { "protected": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9", "signature": "GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs" } ] }, "json_flat": { "payload": "$.02", "protected": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9", "signature": "GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs" } } } rhonabwy-1.1.13/test/cookbook-master/rfc7797/README.md000066400000000000000000000003351452472117100221000ustar00rootroot00000000000000# RFC 7797 Examples - "b64"=false # This repository contains all of the examples from [JSON Web Signature (JWS) Unencoded Payload Option](https://tools.ietf.org/html/rfc7797) along with a couple of additional examples. rhonabwy-1.1.13/test/cookbook-master/rfc7797/hmac-sha2_b64_false.json000066400000000000000000000024521452472117100251060ustar00rootroot00000000000000{ "title": "'b64'=false compatible with compact serialization", "reproducible": true, "input": { "payload": "This is the payload string!", "key": { "kty": "oct", "alg": "HS256", "k":"AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" }, "alg": "HS256" }, "signing": { "protected": { "alg": "HS256", "b64": false, "crit":["b64"] }, "protected_b64u": "eyJhbGciOiJIUzI1NiIsImI2NCI6LCJjcml0IjpbImI2NCJdfQ", "sig-input": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9.This is the payload string!", "sig": "GsyM6AQJbQHY8aQKCbZSPJHzMRWo3HKIlcDuXof7nqs" }, "output": { "compact": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19.This is the payload string!.ciks0B6Hs-amhOqxI5_iG6mPKnMDlWCb7J2Wu7mtIcg", "json": { "payload": "This is the payload string!", "signatures": [ { "protected": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19", "signature": "ciks0B6Hs-amhOqxI5_iG6mPKnMDlWCb7J2Wu7mtIcg" } ] }, "json_flat": { "payload": "This is the payload string!", "protected": "eyJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19", "signature": "ciks0B6Hs-amhOqxI5_iG6mPKnMDlWCb7J2Wu7mtIcg" } } } rhonabwy-1.1.13/test/cookbook.c000066400000000000000000000456101452472117100163710ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define JSON_JWK_3_1_EC_PUBLIC "cookbook-master/jwk/3_1.ec_public_key.json" #define JSON_JWK_3_2_EC_PRIVATE "cookbook-master/jwk/3_2.ec_private_key.json" #define JSON_JWK_3_3_RSA_PUBLIC "cookbook-master/jwk/3_3.rsa_public_key.json" #define JSON_JWK_3_4_RSA_PRIVATE "cookbook-master/jwk/3_4.rsa_private_key.json" #define JSON_JWK_3_5_SYMMETRIC_MAC "cookbook-master/jwk/3_5.symmetric_key_mac_computation.json" #define JSON_JWK_3_6_SYMMETRIC_ENC "cookbook-master/jwk/3_6.symmetric_key_encryption.json" #define JSON_JWS_4_1_RSA_V15 "cookbook-master/jws/4_1.rsa_v15_signature.json" #define JSON_JWS_4_2_RSA_PSS "cookbook-master/jws/4_2.rsa-pss_signature.json" #define JSON_JWS_4_3_ECDSA "cookbook-master/jws/4_3.ecdsa_signature.json" #define JSON_JWS_4_4_HMAC_SHA2 "cookbook-master/jws/4_4.hmac-sha2_integrity_protection.json" #define JSON_JWS_4_5_DETACHED "cookbook-master/jws/4_5.signature_with_detached_content.json" #define JSON_JWS_4_6_PROTECTING_HEADER "cookbook-master/jws/4_6.protecting_specific_header_fields.json" #define JSON_JWS_4_7_PROTECTING_CONTENT "cookbook-master/jws/4_7.protecting_content_only.json" #define JSON_JWS_4_8_MULTIPLE_SIGNATURES "cookbook-master/jws/4_8.multiple_signatures.json" #define JSON_JWE_5_1_RSA_V15_AES_CBC "cookbook-master/jwe/5_1.key_encryption_using_rsa_v15_and_aes-hmac-sha2.json" #define JSON_JWE_5_2_RSA_OAEP_AES_GCM "cookbook-master/jwe/5_2.key_encryption_using_rsa-oaep_with_aes-gcm.json" #define JSON_JWE_5_3_PBES2_AES_CBC "cookbook-master/jwe/5_3.key_wrap_using_pbes2-aes-keywrap_with-aes-cbc-hmac-sha2.json" #define JSON_JWE_5_4_ECDH_ES_AES_GCM "cookbook-master/jwe/5_4.key_agreement_with_key_wrapping_using_ecdh-es_and_aes-keywrap_with_aes-gcm.json" #define JSON_JWE_5_5_ECDH_ES_AES_CBC "cookbook-master/jwe/5_5.key_agreement_using_ecdh-es_with_aes-cbc-hmac-sha2.json" #define JSON_JWE_5_6_DIR_AES_GCM "cookbook-master/jwe/5_6.direct_encryption_using_aes-gcm.json" #define JSON_JWE_5_7_AES_GCM_KEYWRAP_AES_CBC "cookbook-master/jwe/5_7.key_wrap_using_aes-gcm_keywrap_with_aes-cbc-hmac-sha2.json" #define JSON_JWE_5_8_AES_KEYWRAP_AES_GCM "cookbook-master/jwe/5_8.key_wrap_using_aes-keywrap_with_aes-gcm.json" #define JSON_JWE_5_9_COMPRESSED "cookbook-master/jwe/5_9.compressed_content.json" #define JSON_JWE_5_10_AAD "cookbook-master/jwe/5_10.including_additional_authentication_data.json" #define JSON_JWE_5_11_PROTECTING_HEADER "cookbook-master/jwe/5_11.protecting_specific_header_fields.json" #define JSON_JWE_5_12_PROTECTING_CONTENT "cookbook-master/jwe/5_12.protecting_content_only.json" #define JSON_JWE_5_13_MULTIPLE_RECIPIENTS "cookbook-master/jwe/5_13.encrypting_to_multiple_recipients.json" #define JSON_JWS_CURVE25519 "cookbook-master/curve25519/jws.json" #define JSON_JWE_CURVE25519 "cookbook-master/curve25519/ecdh-es.json" static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } static void jws_test(const char * file_path) { char * file_content, * token; json_t * j_content; jws_t * jws; jwk_t * jwk_privkey, * jwk_pubkey; ck_assert_ptr_ne(NULL, file_content = get_file_content(file_path)); ck_assert_ptr_ne(NULL, j_content = json_loads(file_content, JSON_DECODE_ANY, NULL)); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", json_string_value(json_object_get(j_content, "title"))); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_t(jwk_privkey, json_object_get(json_object_get(j_content, "input"), "key")), RHN_OK); if (r_jwk_key_type(jwk_privkey, NULL, 0) & R_KEY_TYPE_PRIVATE) { ck_assert_int_eq(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); } else if (r_jwk_key_type(jwk_privkey, NULL, 0) & R_KEY_TYPE_SYMMETRIC) { ck_assert_int_eq(r_jwk_import_from_json_t(jwk_pubkey, json_object_get(json_object_get(j_content, "input"), "key")), RHN_OK); } if (json_object_get(j_content, "reproducible") == json_true()) { ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "input"), "payload")), json_string_length(json_object_get(json_object_get(j_content, "input"), "payload"))), RHN_OK); ck_assert_int_eq(r_jws_set_full_header_json_t(jws, json_object_get(json_object_get(j_content, "signing"), "protected")), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_t(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne(NULL, token = r_jws_serialize(jws, NULL, 0)); ck_assert_str_eq(token, json_string_value(json_object_get(json_object_get(j_content, "output"), "compact"))); r_jws_free(jws); o_free(token); } ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, json_string_value(json_object_get(json_object_get(j_content, "output"), "compact")), 0), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_t(jws, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); json_decref(j_content); o_free(file_content); } static void jwe_test(const char * file_path) { char * file_content, * token; json_t * j_content, * j_json; jwe_t * jwe, * jwe_c, * jwe_f, * jwe_g; jwk_t * jwk_privkey, * jwk_pubkey; jwks_t * jwks_privkey, * jwks_pubkey; unsigned char iv[128] = {0}, cek[128] = {0}; const unsigned char * payload; size_t iv_len = 0, cek_len = 0, payload_len = 0; ck_assert_ptr_ne(NULL, file_content = get_file_content(file_path)); ck_assert_ptr_ne(NULL, j_content = json_loads(file_content, JSON_DECODE_ANY, NULL)); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", json_string_value(json_object_get(j_content, "title"))); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); if (json_object_get(json_object_get(j_content, "input"), "key") != NULL) { ck_assert_int_eq(r_jwk_import_from_json_t(jwk_privkey, json_object_get(json_object_get(j_content, "input"), "key")), RHN_OK); } else if (json_object_get(json_object_get(j_content, "input"), "pwd") != NULL) { ck_assert_int_eq(r_jwk_import_from_symmetric_key(jwk_privkey, (const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "input"), "pwd")), json_string_length(json_object_get(json_object_get(j_content, "input"), "pwd"))), RHN_OK); } if (r_jwk_key_type(jwk_privkey, NULL, 0) & R_KEY_TYPE_PRIVATE) { ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); } else if (r_jwk_key_type(jwk_privkey, NULL, 0) & R_KEY_TYPE_SYMMETRIC) { ck_assert_ptr_ne(NULL, jwk_pubkey = r_jwk_copy(jwk_privkey)); } ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey), RHN_OK); if (json_object_get(j_content, "reproducible") == json_true()) { ck_assert_int_eq(r_jwe_init(&jwe_c), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_c, (const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "input"), "plaintext")), json_string_length(json_object_get(json_object_get(j_content, "input"), "plaintext"))), RHN_OK); if (json_object_get(json_object_get(j_content, "input"), "alg")) { ck_assert_int_eq(r_jwe_set_alg(jwe_c, r_str_to_jwa_alg(json_string_value(json_object_get(json_object_get(j_content, "input"), "alg")))), RHN_OK); } if (json_object_get(json_object_get(j_content, "input"), "enc")) { ck_assert_int_eq(r_jwe_set_enc(jwe_c, r_str_to_jwa_enc(json_string_value(json_object_get(json_object_get(j_content, "input"), "enc")))), RHN_OK); } if (json_object_get(json_object_get(j_content, "encrypting_content"), "protected") != NULL) { ck_assert_int_eq(r_jwe_set_full_header_json_t(jwe_c, json_object_get(json_object_get(j_content, "encrypting_content"), "protected")), RHN_OK); } ck_assert_int_eq(1, o_base64url_decode((const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "generated"), "iv")), json_string_length(json_object_get(json_object_get(j_content, "generated"), "iv")), iv, &iv_len)); ck_assert_int_eq(r_jwe_set_iv(jwe_c, iv, iv_len), RHN_OK); if (json_object_get(json_object_get(j_content, "generated"), "cek") != NULL) { ck_assert_int_eq(1, o_base64url_decode((const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "generated"), "cek")), json_string_length(json_object_get(json_object_get(j_content, "generated"), "cek")), cek, &cek_len)); ck_assert_int_eq(r_jwe_set_cypher_key(jwe_c, cek, cek_len), RHN_OK); } if (json_object_get(json_object_get(j_content, "input"), "aad") != NULL) { ck_assert_int_eq(r_jwe_set_aad(jwe_c, (const unsigned char *)json_string_value(json_object_get(json_object_get(j_content, "input"), "aad")), json_string_length(json_object_get(json_object_get(j_content, "input"), "aad"))), RHN_OK); } if (json_object_get(json_object_get(j_content, "encrypting_content"), "unprotected") != NULL) { ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe_c, json_object_get(json_object_get(j_content, "encrypting_content"), "unprotected")), RHN_OK); } ck_assert_ptr_ne(NULL, jwe_f = r_jwe_copy(jwe_c)); ck_assert_ptr_ne(NULL, jwe_g = r_jwe_copy(jwe_c)); if (json_object_get(json_object_get(j_content, "output"), "compact") != NULL) { ck_assert_ptr_ne(NULL, token = r_jwe_serialize(jwe_c, jwk_pubkey, 0)); ck_assert_str_eq(token, json_string_value(json_object_get(json_object_get(j_content, "output"), "compact"))); o_free(token); } if (json_object_get(json_object_get(j_content, "output"), "json_flat") != NULL) { ck_assert_ptr_ne(NULL, j_json = r_jwe_serialize_json_t(jwe_f, jwks_pubkey, 0, R_JSON_MODE_FLATTENED)); //y_log_message(Y_LOG_LEVEL_DEBUG, "j_json %s", json_dumps(j_json, JSON_INDENT(2))); //y_log_message(Y_LOG_LEVEL_DEBUG, "reference %s", json_dumps(json_object_get(json_object_get(j_content, "output"), "json_flat"), JSON_INDENT(2))); ck_assert_int_eq(1, json_equal(j_json, json_object_get(json_object_get(j_content, "output"), "json_flat"))); json_decref(j_json); } if (json_object_get(json_object_get(j_content, "output"), "json") != NULL) { ck_assert_ptr_ne(NULL, j_json = r_jwe_serialize_json_t(jwe_g, jwks_pubkey, 0, R_JSON_MODE_GENERAL)); //y_log_message(Y_LOG_LEVEL_DEBUG, "j_json %s", json_dumps(j_json, JSON_INDENT(2))); //y_log_message(Y_LOG_LEVEL_DEBUG, "reference %s", json_dumps(json_object_get(json_object_get(j_content, "output"), "json"), JSON_INDENT(2))); ck_assert_int_eq(1, json_equal(j_json, json_object_get(json_object_get(j_content, "output"), "json"))); json_decref(j_json); } r_jwe_free(jwe_c); r_jwe_free(jwe_f); r_jwe_free(jwe_g); } if (json_object_get(json_object_get(j_content, "output"), "compact") != NULL) { ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, json_string_value(json_object_get(json_object_get(j_content, "output"), "compact")), 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk_privkey, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jwe_get_payload(jwe, &payload_len)); ck_assert_int_eq(payload_len, json_string_length(json_object_get(json_object_get(j_content, "input"), "plaintext"))); ck_assert_int_eq(0, memcmp(payload, json_string_value(json_object_get(json_object_get(j_content, "input"), "plaintext")), payload_len)); r_jwe_free(jwe); } if (json_object_get(json_object_get(j_content, "output"), "json") != NULL) { ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_t(jwe, json_object_get(json_object_get(j_content, "output"), "json"), 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk_privkey, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jwe_get_payload(jwe, &payload_len)); ck_assert_int_eq(payload_len, json_string_length(json_object_get(json_object_get(j_content, "input"), "plaintext"))); ck_assert_int_eq(0, memcmp(payload, json_string_value(json_object_get(json_object_get(j_content, "input"), "plaintext")), payload_len)); r_jwe_free(jwe); } if (json_object_get(json_object_get(j_content, "output"), "json_flat") != NULL) { ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_t(jwe, json_object_get(json_object_get(j_content, "output"), "json_flat"), 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk_privkey, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jwe_get_payload(jwe, &payload_len)); ck_assert_int_eq(payload_len, json_string_length(json_object_get(json_object_get(j_content, "input"), "plaintext"))); ck_assert_int_eq(0, memcmp(payload, json_string_value(json_object_get(json_object_get(j_content, "input"), "plaintext")), payload_len)); r_jwe_free(jwe); } r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwks_free(jwks_privkey); r_jwks_free(jwks_pubkey); json_decref(j_content); o_free(file_content); } START_TEST(test_rhonabwy_cookbook_jwk) { char * file_content; jwk_t * jwk; unsigned int bits = 0; y_log_message(Y_LOG_LEVEL_INFO, "Test JWK"); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_1_EC_PUBLIC, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_1_EC_PUBLIC)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_EC|R_KEY_TYPE_PUBLIC); ck_assert_int_eq(521, bits); r_jwk_free(jwk); o_free(file_content); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_2_EC_PRIVATE, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_2_EC_PRIVATE)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_EC|R_KEY_TYPE_PRIVATE); ck_assert_int_eq(521, bits); r_jwk_free(jwk); o_free(file_content); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_3_RSA_PUBLIC, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_3_RSA_PUBLIC)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_RSA|R_KEY_TYPE_PUBLIC); ck_assert_int_eq(2048, bits); r_jwk_free(jwk); o_free(file_content); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_4_RSA_PRIVATE, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_4_RSA_PRIVATE)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_RSA|R_KEY_TYPE_PRIVATE); ck_assert_int_eq(2048, bits); r_jwk_free(jwk); o_free(file_content); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_5_SYMMETRIC_MAC, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_5_SYMMETRIC_MAC)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_HMAC|R_KEY_TYPE_SYMMETRIC); ck_assert_int_eq(256, bits); r_jwk_free(jwk); o_free(file_content); y_log_message(Y_LOG_LEVEL_INFO, "Run test: %s", o_strrchr(JSON_JWK_3_6_SYMMETRIC_ENC, '/')+1); ck_assert_ptr_ne(NULL, file_content = get_file_content(JSON_JWK_3_6_SYMMETRIC_ENC)); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, file_content), RHN_OK); ck_assert_int_eq(r_jwk_key_type(jwk, &bits, 0), R_KEY_TYPE_HMAC|R_KEY_TYPE_SYMMETRIC); ck_assert_int_eq(256, bits); r_jwk_free(jwk); o_free(file_content); } END_TEST START_TEST(test_rhonabwy_cookbook_jws) { y_log_message(Y_LOG_LEVEL_INFO, "Test JWS"); jws_test(JSON_JWS_4_1_RSA_V15); #if GNUTLS_VERSION_NUMBER >= 0x030600 jws_test(JSON_JWS_4_2_RSA_PSS); jws_test(JSON_JWS_4_3_ECDSA); jws_test(JSON_JWS_CURVE25519); #endif jws_test(JSON_JWS_4_4_HMAC_SHA2); //jws_test(JSON_JWS_4_5_DETACHED); //jws_test(JSON_JWS_4_6_PROTECTING_HEADER); //jws_test(JSON_JWS_4_7_PROTECTING_CONTENT); //jws_test(JSON_JWS_4_8_MULTIPLE_SIGNATURES); } END_TEST START_TEST(test_rhonabwy_cookbook_jwe) { y_log_message(Y_LOG_LEVEL_INFO, "Test JWE"); jwe_test(JSON_JWE_5_1_RSA_V15_AES_CBC); // Not reproductible yet #if NETTLE_VERSION_NUMBER >= 0x030400 jwe_test(JSON_JWE_5_2_RSA_OAEP_AES_GCM); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d jwe_test(JSON_JWE_5_3_PBES2_AES_CBC); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 jwe_test(JSON_JWE_5_4_ECDH_ES_AES_GCM); jwe_test(JSON_JWE_5_5_ECDH_ES_AES_CBC); #endif jwe_test(JSON_JWE_5_6_DIR_AES_GCM); #if NETTLE_VERSION_NUMBER >= 0x030400 jwe_test(JSON_JWE_5_7_AES_GCM_KEYWRAP_AES_CBC); jwe_test(JSON_JWE_5_8_AES_KEYWRAP_AES_GCM); jwe_test(JSON_JWE_5_9_COMPRESSED); jwe_test(JSON_JWE_5_10_AAD); jwe_test(JSON_JWE_5_11_PROTECTING_HEADER); //jwe_test(JSON_JWE_5_12_PROTECTING_CONTENT); // Not sure if relevant //jwe_test(JSON_JWE_5_13_MULTIPLE_RECIPIENTS); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 jwe_test(JSON_JWE_CURVE25519); #endif } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy cookbook tests"); tc_core = tcase_create("test_rhonabwy_cookbook"); tcase_add_test(tc_core, test_rhonabwy_cookbook_jwk); tcase_add_test(tc_core, test_rhonabwy_cookbook_jws); tcase_add_test(tc_core, test_rhonabwy_cookbook_jwe); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy cookbook tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_aesgcm.c000066400000000000000000000404171452472117100166670ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define TOKEN "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_HEADER "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklL.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_ENCRYPTED_KEY "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-P63Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_IV "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XW6hRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFF6oUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_TAG "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.86_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaq" #define TOKEN_INVALID_TAG_SMALL "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdiJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaq" #define TOKEN_INVALID_TAG_TYPE "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjo0Mn0.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_HEADER_B64 ";error;.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.;error;.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_IV_LEN "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJjR3h2Y0FvIiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_IV_TYPE "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOjQyLCJ0YWciOiJyVjB2dk9fUkxlMElEM25qbnBySUtnIn0.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.;error;.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.;error;" #define TOKEN_INVALID_DOTS "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJTTWdHekVEMHBNY05wQk00IiwidGFnIjoiclYwdnZPX1JMZTBJRDNuam5wcklLZyJ9xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" #define TOKEN_INVALID_HEADER_IV_TAG "eyJhbGciOiJBMTI4R0NNS1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiaXYiOiJaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eUNnIiwidGFnIjoiWlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlDZyJ9Cg.xB-j-EVsBqwgxSMQEfsJzGfCuvsbw9ZmcbrYKFmeHiQ.XWChRAUirGixPLf5_-Pa3Q.Ck5akPNhJPlTKH30kFuadoOwcQuV1AUmLtOYjGFFsoUEr1U2H0y49zrNc6TTmlkX1T2TRTOPAaTqtb1_1YEg8A.8v_65BtY-tYA1QzBaqUcKA" const char jwk_key_128_1[] = "{\"kty\":\"oct\",\"k\":\"Zd3bPKCfbPc2A6sh3M7dIQ\"}"; const char jwk_key_128_2[] = "{\"kty\":\"oct\",\"k\":\"ELG-YDhuRKg-6zH2QTR7Tg\"}"; START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_IV_TAG, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_LEN, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_TYPE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_SMALL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_TYPE, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; jwk_t * jwk; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENCRYPTED_KEY, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_ERROR_INVALID); r_jwk_free(jwk); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_invalid_privkey) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_enc, * jwk_dec; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_enc), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_dec), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_enc, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_dec, jwk_key_128_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128GCMKW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_enc, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_dec, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_enc); r_jwk_free(jwk_dec); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128GCMKW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_2_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128GCMKW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128GCMKW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_serialize_invalid_iv) { jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128GCMKW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "iv", ""), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "iv", ";error;"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "iv", "cGxvcA"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "iv", 42), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); r_jwe_free(jwe); r_jwk_free(jwk); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE AES GCM key encryption tests"); tc_core = tcase_create("test_rhonabwy_aesgcm"); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_invalid_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_2_ok); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_serialize_invalid_iv); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE AES GCM key encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_core.c000066400000000000000000002522761452472117100163700ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define HUGE_PAYLOAD "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis efficitur lectus sit amet libero gravida eleifend. Nulla aliquam accumsan erat, quis tincidunt purus ultricies eu. Aenean eu dui ac diam placerat mollis. Duis eget tempor ipsum, vel ullamcorper purus. Ut eget quam vehicula, congue urna vel, dictum risus. Duis tristique est sed diam lobortis commodo. Proin et urna in odio malesuada sagittis. Donec lectus ligula, porttitor sed lorem ut, malesuada posuere neque. Nullam et nisl a felis congue mattis id non lectus.\ Quisque viverra hendrerit malesuada. Integer sollicitudin magna purus, in dignissim eros ullamcorper et. Praesent dignissim metus neque, eget tempor dolor tincidunt egestas. Nulla odio risus, tincidunt et egestas aliquet, pellentesque et eros. Etiam mattis orci a dui efficitur pharetra. Donec fermentum sem sed lacus finibus, nec luctus nisl vulputate. Donec sodales, nisi sed posuere maximus, lectus elit fermentum sapien, quis volutpat risus nisl vel dui. In vitae ante diam.\ Vivamus a nisl quam. Proin in lectus nunc. Aliquam condimentum tellus non feugiat aliquam. Nulla eu mi ligula. Proin auctor varius massa sed consectetur. Nulla et ligula pellentesque, egestas dui eu, gravida arcu. Maecenas vehicula feugiat tincidunt. Aenean sed sollicitudin ex. Cras luctus facilisis erat eu pharetra. Vestibulum interdum consequat tellus nec sagittis. Aliquam tincidunt eget lectus non bibendum. Mauris ut consectetur diam.\ Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed lorem lectus, ullamcorper consectetur quam ut, pharetra consectetur diam. Suspendisse eu erat quis nunc imperdiet lacinia vitae id arcu. Fusce non euismod urna. Aenean lacinia porta tellus nec rutrum. Aliquam est magna, aliquam non hendrerit eget, scelerisque quis sapien. Quisque consectetur et lacus non dapibus. Duis diam purus, vulputate convallis faucibus in, rutrum quis mi. Sed sed magna eget tellus semper suscipit a in augue.\ Aenean vitae tortor quam. Praesent pulvinar nulla a nisi egestas, laoreet tempus mauris ullamcorper. Nam vulputate molestie velit, quis laoreet felis suscipit euismod. Pellentesque a enim dapibus, tincidunt lorem vel, suscipit turpis. Phasellus id metus vehicula, luctus sem nec, maximus purus. Duis dictum elit quam, quis rhoncus ex ullamcorper ut. Donec fringilla augue vitae vestibulum maximus. Mauris vel arcu eget arcu bibendum ornare." const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0Cg\"}"; const unsigned char symmetric_key[] = "my-very-secret"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; const unsigned char rsa_2048_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\n" "iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\n" "lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\n" "Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\n" "TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\n" "45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\n" "2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\n" "n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\n" "wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\n" "z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\n" "3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\n" "UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\n" "DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\n" "DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\n" "m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\n" "cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\n" "1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\n" "I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\n" "INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\n" "vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\n" "Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\n" "TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\n" "+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\n" "mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\n" "LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\n" "tEOtzsP5GMDYVlEp1jYSjzQ=\n" "-----END PRIVATE KEY-----\n"; #define CLAIM_STR "grut" #define CLAIM_INT 42 unsigned char cypher_key[] = {4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}; unsigned char iv[] = {3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}; unsigned char aad[] = {82, 110, 74, 112, 90, 87, 53, 107, 99, 50, 104, 112, 99, 67, 66, 112, 99, 121, 66, 116, 89, 87, 100, 112, 89, 119, 111}; #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" const unsigned char advanced_key_1[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIAYMcQvkJcMXw5WYHEL05zOvksZ3JG6WAVc4PqupNxncoAoGCCqGSM49\n" "AwEHoUQDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5\n" "plYuZz2/TzJbrwPDUYCB/rV8/hHku0tXnA==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_1[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu\n" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg\n" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG\n" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1\n" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF\n" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1\n" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd\n" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2\n" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU\n" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv\n" "s3yOHp3+WqTOfToYSrrNz2rP\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_1[] = "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv" "s3yOHp3+WqTOfToYSrrNz2rP"; const unsigned char advanced_key_2[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEICXdcvJ68jTD5qOxv5a1QQLE7K6OcqSOjgNLd3pPE1z1oAoGCCqGSM49\n" "AwEHoUQDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3\n" "n5/ijLyQ54f6bWnLkxeuZxRfTdrDHNodOg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_2[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i\n" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE\n" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y\n" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A\n" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A\n" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP\n" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J\n" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy\n" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV\n" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE\n" "TrY5XLCqtITFRVTMubJPyDnc\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_2[] = "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE" "TrY5XLCqtITFRVTMubJPyDnc"; const unsigned char advanced_key_3[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIEslWGWIe3xz8KResadYE+JZEfrPNp4wV7b19He998GLoAoGCCqGSM49\n" "AwEHoUQDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABU\n" "Xm1qDJIFMq/Ct9//ZMw3cHcvzJSDsqOuLQ==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_3[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUF6BNJxZDAJ79e+0I4OStbeBHNB4wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5NDBaFw0yMjA4MjkyMTQ5NDBaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABUXm1q\n" "DJIFMq/Ct9//ZMw3cHcvzJSDsqOuLaN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdgOkpqrAK\n" "R71zgTVIPfKcF40SAzAfBgNVHSMEGDAWgBREM51ULZjY5niamwAnB62dRTAjZDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHe+d5uxOBNW+6o9gyn+g2Q1x0YFJhaCvvgoVVC71\n" "E1WkdBMO0nRYJZNxmNgd13DNvrD+Y31IFmTgGidg9urDq6HLo9Q9UkpAYdOKTsXk\n" "NDo1QL5Kjqspuf2Aco3cDcvR2a5OUAJigftpdjOSTvG3geltDsYcd/khY0dMOl3h\n" "25OZm6KyZAORWw3LhXxtmDfPxe31cd/lEp19Gp8aokLorHc7/yYS5h4OhL146vm/\n" "CHYSt8pAIP65IyKoHJpHdSc4uOz0HJ92lpR10Qa9wqrFzDVcHGDX/JBvS0/H5Uyd\n" "OY4jO7FEImq434YOtSy0yGJh/soK8RNe0frGzoQsQ/WxMBeHnprp/eBVZ8jqvYJ4\n" "GW8kTtl8SGitehjoFdby46nAzdt3dBUcmZhm9Yka4jRVN5mwd+s13Pu2zRSvEwvq\n" "IiKlSjZYotFffUsrfHVYqlk58PX5j7P/fohvLnHkucbu9FVrvVLlqZHK3vzafdw6\n" "SlefNWD4/90X/5VFOpePkjZY\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_3[] = "MIIDDjCCAXagAwIBAgIUcqJBzjg4lb0vBeFBGZ2uuY9ZoLkwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzlaFw0yMjA4MjkyMTQ5MzlaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAE/TPAuX0MdUL6H1xse1VwixvR6wxmy6+GS5XS4P8H6lcczryuu+8Oqz2h" "6sw1ChDIRt00l25j92h1SjFknnbE2qN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBScRf4VnU2d" "71JxFeUmXa5uqaMclTAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAmhXg8uHQcAttx1gOKrLi77q1RpeGIu4dYy0UtOW1" "ucNJuOGs8prcPROPElZEkZmfcgwDd2wwjNfs8tqPrcgSDyipLG7yMEj3uxxSZW7S" "DN72f3qL2QavZ4joVZI5v2VplBFbCqC3Fr06Pg8xRcihfb+SnsrhQ4hVuG6GxIF+" "n/khTXsEW6kEi6V0s79AIFBzYa/nH3sfK4gWQvcmUoBJ3Hzz2EIroB9v+P8OdJcR" "37pfw+IDZx2Ri/W18nLwDTF0NVydT2ZGxHRFjankV2uM5q79nW1fsRCTrfoKxWGN" "pKG9IxeXORwv87pETRxQA8W08AGqBsk62f5/lEuxfJqIw6wZKLtb2nqN912QDXLc" "q0F6StYQHYB7WMZM2FA3AzaYeCjfI5a1/LirKm8okt96HXVo2rpqaDB3sJq5C5u+" "yUZ3i+PlDEkUv3CTYSVYaBjKBDTgj6Z4kxKTdBE/A5rXRwIi14LyddTcPRKDrHlh" "MQJL7ADzfeTbVYOHJx8XEE0F"; const unsigned char advanced_key_4[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIF+8UMnI9we1opth9BXqoNmsyj7bpeyMl6gnj8y4jejaoAoGCCqGSM49\n" "AwEHoUQDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6\n" "KeiN/+ym/O780uZLwqCaFR9ix5I3/Jxpdg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_4[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN\n" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho\n" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA\n" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw\n" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw\n" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a\n" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8\n" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ\n" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N\n" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa\n" "Cggnp64OVIyU5OqLa4BVmWQl\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_4[] = "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa" "Cggnp64OVIyU5OqLa4BVmWQl"; const char advanced_jku_4[] = "{\"keys\":[{\"kty\":\"EC\",\"x\":\"rXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLc\",\"y\":\"Rf9u09u0einojf_spvzu_NLmS8KgmhUfYseSN_ycaXY\",\"crv\":\"P-256\",\"kid\":\"OsipzlLJ1CAOU_WnT2zuB4u31IlgFPsZfT4j4r5qZUA\"}]}"; const char jwk_key_128_1[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"Zd3bPKCfbPc2A6sh3M7dIbzgD6PS-qIwsbN79VgN5PY\"}"; #define ADVANCED_TOKEN "eyJraWQiOiJkZjVTckx2SlgzWEI3OHhHa25QZVZDemdXOTZhT2pYSTlfQnFtYkUzV0ljIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRUNESC1FUytBMTI4S1ciLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoicDBRRHpqVU5HVTJ0UmM4QlNPbFpzRzBONTQwazNmTzBPT082bTJjbDlJSSIsInkiOiItTEkwRjdwbC1yNklYZjlXMVpMVFRDZXV3M05JemZRLW1OamVJS2RJc1RVIiwiY3J2IjoiUC0yNTYifSwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9.jJY1hvX8J0f8T-8piAS_9zVejfTVV-oUaflrY7WV0ErmiNlYc7aHRg.bToigkLnPUDJb_P4cHt0hA.lLYVB2ajc0KNPt2iAvP2LFxDAjI1ujqKkjgZ1--8seq63WF0jZD9CxKRUUseIAmEjiPpaOG1co8DdqUXMEvw2g.MnoGVwEN_PG2i_joWhxTUA" #define TOKEN "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_HEADER "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_HEADER_B64 ";error;iOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.;error;nK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.;error;czZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_CIPHER_LEN "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..-cNn1XCsgQJ4LUqRynkFYg.10CSSm6dThI4bPCQjzSrEupjI-sTLk52MEGEf06vxJDabMOAdfcyIlLa4CMJyOmFMpVvI9-eWRfLmoIM8R.r76qF3OECfzhDMxZ7yTGFg" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.;error;Z3gDEpAMD_79pOw" #define TOKEN_INVALID_DOTS "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_EMPTY_HEADER ".S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_EMPTY_IV "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q..BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_EMPTY_CIPHERTEXT "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ..p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_EMPTY_TAG "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g." #define TOKEN_OVERSIZE_IV "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.ZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yCg.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_OVERSIZE_TAG "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.ZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yZXJyb3JlcnJvcmVycm9yCg" #define TOKEN_INVALID_ENC "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_VALID_CIPHER_LEN_1 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_1 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_1_2 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2IcBE6yb.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_1_3 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5V.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_1_4 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2IcBE6y.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_VALID_CIPHER_LEN_2 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_2 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0F.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_2_2 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZFBE6y.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_2_3 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_LEN_2_4 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.AwliP-KmWgsZ37BvzCefNen6VTbRK3QMA4TkvRkH0tP1bTdhtFJgJxeVmJkLD61A1hnWGetdg11c9ADsnWgL56NyxwSYjU1ZEHcGkd3EkU0vjHi9gTlb90qSYFfeF0LwkcTtjbYKCsiNJQkcIp1yeM03OmuiYSoYJVSpf7ej6zaYcMv3WwdxDFl8REwOhNImk2Xld2JXq6BR53TSFkyT7PwVLuq-1GwtGHlQeg7gDT6xW0JqHDPn_H-puQsmthc9Zg0ojmJfqqFvETUxLAF-KjcBTS5dNy6egwkYtOt8EIHK-oEsKYtZRaa8Z7MOZ7UGxGIMvEmxrGCPeJa14slv2-gaqK0kEThkaSqdYw0FkQZFBE6yb.xrblYm4FGTv2j59L7xQgAA" START_TEST(test_rhonabwy_init) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_payload) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(NULL, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, 0), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, NULL, o_strlen(PAYLOAD)), RHN_OK); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_alg) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_UNKNOWN); ck_assert_int_eq(r_jwe_set_alg(NULL, R_JWA_ALG_RSA1_5), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_RSA1_5); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_ECDH_ES); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_set_header) { jwe_t * jwe; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(NULL, "key", "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, NULL, "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "key", "value"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_int_value(NULL, "key", 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, NULL, 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "key", 42), RHN_OK); ck_assert_int_eq(r_jwe_set_header_json_t_value(NULL, "key", j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, NULL, j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, "key", j_value), RHN_OK); json_decref(j_value); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_get_header) { jwe_t * jwe; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_result; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, "keyjson", j_value), RHN_OK); ck_assert_str_eq("value", r_jwe_get_header_str_value(jwe, "keystr")); ck_assert_int_eq(42, r_jwe_get_header_int_value(jwe, "keyint")); ck_assert_int_eq(json_equal(j_value, (j_result = r_jwe_get_header_json_t_value(jwe, "keyjson"))) , 1); ck_assert_ptr_eq(NULL, r_jwe_get_header_str_value(jwe, "error")); ck_assert_int_eq(0, r_jwe_get_header_int_value(jwe, "error")); ck_assert_ptr_eq(NULL, r_jwe_get_header_json_t_value(jwe, "error")); json_decref(j_value); json_decref(j_result); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_set_full_header_error) { jwe_t * jwe; json_t * j_header; j_header = json_pack("{ssss}", "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", "error"); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_t(jwe, j_header), RHN_ERROR_PARAM); r_jwe_free(jwe); json_decref(j_header); j_header = json_pack("{ssss}", "alg", "error", "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_t(jwe, j_header), RHN_ERROR_PARAM); r_jwe_free(jwe); json_decref(j_header); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_t(jwe, NULL), RHN_ERROR_PARAM); r_jwe_free(jwe); j_header = json_pack("{ssss}", "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); ck_assert_int_eq(r_jwe_set_full_header_json_t(NULL, j_header), RHN_ERROR_PARAM); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_set_full_header) { jwe_t * jwe; json_t * j_header = json_pack("{sssisossss}", "str", CLAIM_STR, "int", CLAIM_INT, "obj", json_true(), "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); char * str_header = json_dumps(j_header, JSON_COMPACT); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_t(jwe, j_header), RHN_OK); ck_assert_str_eq(r_jwe_get_header_str_value(jwe, "str"), CLAIM_STR); ck_assert_int_eq(r_jwe_get_header_int_value(jwe, "int"), CLAIM_INT); ck_assert_ptr_eq(r_jwe_get_header_json_t_value(jwe, "obj"), json_true()); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_RSA_OAEP_256); ck_assert_int_eq(r_jwe_get_enc(jwe), R_JWA_ENC_A256GCM); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_str(jwe, str_header), RHN_OK); ck_assert_str_eq(r_jwe_get_header_str_value(jwe, "str"), CLAIM_STR); ck_assert_int_eq(r_jwe_get_header_int_value(jwe, "int"), CLAIM_INT); ck_assert_ptr_eq(r_jwe_get_header_json_t_value(jwe, "obj"), json_true()); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_RSA_OAEP_256); ck_assert_int_eq(r_jwe_get_enc(jwe), R_JWA_ENC_A256GCM); r_jwe_free(jwe); o_free(str_header); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_get_full_header) { jwe_t * jwe; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_header = json_pack("{sssisO}", "keystr", "value", "keyint", 42, "keyjson", j_value), * j_result; ck_assert_ptr_ne(j_header, NULL); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, "keyjson", j_value), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(json_equal(j_header, (j_result = r_jwe_get_full_header_json_t(jwe))) , 1); json_decref(j_value); json_decref(j_header); json_decref(j_result); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_set_full_unprotected_header) { jwe_t * jwe; json_t * j_header = json_pack("{sssiso}", "str", CLAIM_STR, "int", CLAIM_INT, "obj", json_true()); char * str_header = json_dumps(j_header, JSON_COMPACT); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, json_null()), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(NULL, j_header), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_header), RHN_OK); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_str(jwe, "[4, 8, 15, 16, 23, 42]"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_str(jwe, NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_str(NULL, str_header), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_str(jwe, str_header), RHN_OK); r_jwe_free(jwe); o_free(str_header); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_get_full_unprotected_header) { jwe_t * jwe; json_t * j_header = json_pack("{sssiso}", "str", CLAIM_STR, "int", CLAIM_INT, "obj", json_true()), * j_header_get; char * str_header_get; ck_assert_ptr_ne(j_header, NULL); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_header), RHN_OK); ck_assert_ptr_ne(NULL, j_header_get = r_jwe_get_full_unprotected_header_json_t(jwe)); ck_assert_int_eq(1, json_equal(j_header_get, j_header)); json_decref(j_header_get); ck_assert_ptr_ne(NULL, str_header_get = r_jwe_get_full_unprotected_header_str(jwe)); ck_assert_ptr_ne(NULL, j_header_get = json_loads(str_header_get, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(1, json_equal(j_header_get, j_header)); o_free(str_header_get); json_decref(j_header); json_decref(j_header_get); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_set_keys) { jwe_t * jwe; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa, * jwk_key_symmetric; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_pubkey_rsa, jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_key_symmetric, NULL), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(NULL, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_key_symmetric); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_set_jwks) { jwe_t * jwe; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; jwks_t * jwks_pubkey, * jwks_privkey, * jwks; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_rsa), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(0, r_jwks_size(jwe->jwks_privkey)); ck_assert_int_eq(0, r_jwks_size(jwe->jwks_pubkey)); ck_assert_int_eq(r_jwe_add_jwks(jwe, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_int_eq(2, r_jwks_size(jwe->jwks_privkey)); ck_assert_int_eq(2, r_jwks_size(jwe->jwks_pubkey)); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_add_keys_by_content) { jwe_t * jwe; jwk_t * jwk_priv, * jwk_pub; jwks_t * jwks; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t g_privkey; gnutls_pubkey_t g_pubkey; #endif json_t * j_privkey, * j_pubkey; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_rsa_str), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(g_privkey = r_jwk_export_to_gnutls_privkey(jwk_priv), NULL); ck_assert_ptr_ne(g_pubkey = r_jwk_export_to_gnutls_pubkey(jwk_pub, 0), NULL); #endif ck_assert_ptr_ne(j_privkey = r_jwk_export_to_json_t(jwk_priv), NULL); ck_assert_ptr_ne(j_pubkey = r_jwk_export_to_json_t(jwk_pub), NULL); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwe_add_keys_json_t(jwe, j_privkey, j_pubkey), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwe_add_keys_pem_der(jwe, R_FORMAT_PEM, rsa_2048_priv, sizeof(rsa_2048_priv), rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwe_add_key_symmetric(jwe, symmetric_key, sizeof(symmetric_key)), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwe_add_keys_gnutls(jwe, g_privkey, g_pubkey), RHN_OK); jwks = r_jwe_get_jwks_privkey(jwe); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwe_get_jwks_pubkey(jwe); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); #endif r_jwe_free(jwe); #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_deinit(g_privkey); gnutls_pubkey_deinit(g_pubkey); #endif json_decref(j_privkey); json_decref(j_pubkey); r_jwk_free(jwk_priv); r_jwk_free(jwk_pub); } END_TEST START_TEST(test_rhonabwy_set_properties_error) { jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_FULL_JSON_STR, json_true(), RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_FULL_JSON_STR, "{}", RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_INT_VALUE, "key", CLAIM_INT, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_RHN_INT_VALUE, "key", CLAIM_INT, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_JSON_T_VALUE, "key", json_true(), RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_CLAIM_STR_VALUE, "key", CLAIM_STR, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_SIGN_KEY_JWK, jwk, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_VERIFY_KEY_JWK, jwk, RHN_OPT_NONE), RHN_ERROR_PARAM); r_jwe_free(jwe); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_set_properties) { jwe_t * jwe; jwk_t * jwk; const unsigned char * key_iv_aad; size_t key_iv_aad_len; json_t * j_un_header = json_pack("{ss ss ss ss ss ss}", "Twilight Sparkle", "six-pointed star", "Applejack", "trio of apples", "Rainbow Dash", "rainbow-colored lightning bolt with a cloud", "Pinkie Pie", "trio of balloons", "Rarity", "trio of diamonds", "Fluttershy", "trio of butterflies"), * j_un_header_resp; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_properties(jwe, RHN_OPT_HEADER_INT_VALUE, "int", CLAIM_INT, RHN_OPT_HEADER_RHN_INT_VALUE, "rhn_int", (rhn_int_t)CLAIM_INT, RHN_OPT_HEADER_STR_VALUE, "str", CLAIM_STR, RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_UN_HEADER_FULL_JSON_T, j_un_header, RHN_OPT_PAYLOAD, PAYLOAD, o_strlen(PAYLOAD), RHN_OPT_ENC_ALG, R_JWA_ALG_RSA1_5, RHN_OPT_ENC, R_JWA_ENC_A256GCM, RHN_OPT_CIPHER_KEY, cypher_key, sizeof(cypher_key), RHN_OPT_IV, iv, sizeof(iv), RHN_OPT_AAD, aad, sizeof(aad), RHN_OPT_ENCRYPT_KEY_JWK, jwk, RHN_OPT_DECRYPT_KEY_JWK, jwk, RHN_OPT_NONE), RHN_OK); ck_assert_int_eq(CLAIM_INT, r_jwe_get_header_int_value(jwe, "int")); ck_assert_int_eq(CLAIM_INT, r_jwe_get_header_int_value(jwe, "rhn_int")); ck_assert_str_eq(CLAIM_STR, r_jwe_get_header_str_value(jwe, "str")); ck_assert_ptr_eq(json_true(), r_jwe_get_header_json_t_value(jwe, "json")); ck_assert_ptr_ne(NULL, j_un_header_resp = r_jwe_get_full_unprotected_header_json_t(jwe)); ck_assert_int_eq(1, json_equal(j_un_header_resp, j_un_header)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_payload(jwe, &key_iv_aad_len)); ck_assert_int_eq(o_strlen(PAYLOAD), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, PAYLOAD, key_iv_aad_len)); ck_assert_int_eq(R_JWA_ALG_RSA1_5, r_jwe_get_alg(jwe)); ck_assert_int_eq(R_JWA_ENC_A256GCM, r_jwe_get_enc(jwe)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_cypher_key(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(cypher_key), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, cypher_key, key_iv_aad_len)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_iv(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(iv), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, iv, key_iv_aad_len)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_aad(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(aad), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, aad, key_iv_aad_len)); ck_assert_int_eq(1, r_jwks_size(jwe->jwks_privkey)); ck_assert_int_eq(1, r_jwks_size(jwe->jwks_pubkey)); json_decref(j_un_header); json_decref(j_un_header_resp); r_jwe_free(jwe); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_copy) { jwe_t * jwe, * jwe_copy; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL, * token_copy; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_privkey, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_ptr_ne((jwe_copy = r_jwe_copy(jwe)), NULL); ck_assert_ptr_ne((token_copy = r_jwe_serialize(jwe_copy, NULL, 0)), NULL); o_free(token); o_free(token_copy); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_copy); } END_TEST START_TEST(test_rhonabwy_generate_cypher_key) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_gt(jwe->key_len, 0); ck_assert_ptr_ne(jwe->key, NULL); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_generate_iv) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_gt(jwe->iv_len, 0); ck_assert_ptr_ne(jwe->iv, NULL); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_get_set_key_iv_aad) { jwe_t * jwe; const unsigned char * key_iv_aad; size_t key_iv_aad_len; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_cypher_key(jwe, cypher_key, sizeof(cypher_key)), RHN_OK); ck_assert_int_eq(r_jwe_set_iv(jwe, iv, sizeof(iv)), RHN_OK); ck_assert_int_eq(r_jwe_set_aad(jwe, aad, sizeof(aad)), RHN_OK); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_cypher_key(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(cypher_key), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, cypher_key, key_iv_aad_len)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_iv(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(iv), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, iv, key_iv_aad_len)); ck_assert_ptr_ne(NULL, key_iv_aad = r_jwe_get_aad(jwe, &key_iv_aad_len)); ck_assert_int_eq(sizeof(aad), key_iv_aad_len); ck_assert_int_eq(0, memcmp(key_iv_aad, aad, key_iv_aad_len)); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_payload_invalid) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_iv(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_ERROR_PARAM); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_payload) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_payload_all_format) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); // R_JWA_ENC_A192GCM not supported by GnuTLS until 3.6.14 #if GNUTLS_VERSION_NUMBER >= 0x03060e ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192GCM), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); r_jwe_free(jwe); #endif ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_decrypt_payload_invalid_key_no_tag) { char payload_control[] = PAYLOAD; jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); jwe->key[18]++; ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_ne(memcmp(payload_control, jwe->payload, jwe->payload_len), 0); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_payload_zip) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); r_jwe_set_header_str_value(jwe, "zip", "DEF"); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(PAYLOAD))); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_generate_iv(jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)HUGE_PAYLOAD, o_strlen(HUGE_PAYLOAD)), RHN_OK); ck_assert_ptr_eq(jwe->ciphertext_b64url, NULL); r_jwe_set_header_str_value(jwe, "zip", "DEF"); ck_assert_int_eq(r_jwe_encrypt_payload(jwe), RHN_OK); ck_assert_ptr_ne(jwe->ciphertext_b64url, NULL); ck_assert_int_eq(r_jwe_decrypt_payload(jwe), RHN_OK); ck_assert_int_eq(0, o_strncmp(HUGE_PAYLOAD, (const char *)r_jwe_get_payload(jwe, NULL), o_strlen(HUGE_PAYLOAD))); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_key_invalid) { jwe_t * jwe; jwk_t * jwk_pubkey_rsa; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_key(jwe, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(r_jwe_encrypt_key(jwe, NULL, 0), RHN_ERROR_PARAM); r_jwe_free(jwe); r_jwk_free(jwk_pubkey_rsa); } END_TEST START_TEST(test_rhonabwy_encrypt_key_valid) { jwe_t * jwe; jwk_t * jwk_pubkey_rsa; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(o_strlen((const char *)jwe->encrypted_key_b64url), 0); ck_assert_int_eq(r_jwe_encrypt_key(jwe, jwk_pubkey_rsa, 0), RHN_OK); ck_assert_int_gt(o_strlen((const char *)jwe->encrypted_key_b64url), 0); r_jwe_free(jwe); r_jwk_free(jwk_pubkey_rsa); } END_TEST #if GNUTLS_VERSION_NUMBER >= 0x030600 // This test crashes on old gnutls version (3.4 ubuntu xenial) START_TEST(test_rhonabwy_decrypt_key_invalid_encrypted_key) { jwe_t * jwe; jwk_t * jwk_pubkey_rsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); ck_assert_int_eq(o_strlen((const char *)jwe->encrypted_key_b64url), 0); ck_assert_int_eq(r_jwe_encrypt_key(jwe, jwk_pubkey_rsa, 0), RHN_OK); ck_assert_int_gt(o_strlen((const char *)jwe->encrypted_key_b64url), 0); ck_assert_int_eq(r_jwe_decrypt_key(jwe, jwk_pubkey_rsa, 0), RHN_ERROR_INVALID); if (jwe->encrypted_key_b64url[2] == 'a') { jwe->encrypted_key_b64url[2] = 'e'; } else { jwe->encrypted_key_b64url[2] = 'a'; } ck_assert_int_eq(r_jwe_decrypt_key(jwe, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_jwk_in_header_invalid) { jwe_t * jwe, * jwe_parsed; jwk_t * jwk_pubkey_rsa; json_t * j_jwk; char * str_jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_parsed), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_ptr_ne(NULL, j_jwk = json_loads(jwk_privkey_rsa_str, JSON_DECODE_ANY, 0)); ck_assert_int_eq(r_jwe_set_header_json_t_value(jwe, "jwk", j_jwk), RHN_OK); ck_assert_ptr_ne(NULL, str_jwe = r_jwe_serialize(jwe, jwk_pubkey_rsa, 0)); ck_assert_int_eq(r_jwe_parse(jwe_parsed, str_jwe, 0), RHN_ERROR_PARAM); r_jwe_free(jwe); r_jwe_free(jwe_parsed); r_jwk_free(jwk_pubkey_rsa); json_decref(j_jwk); o_free(str_jwe); } END_TEST #endif START_TEST(test_rhonabwy_decrypt_key_valid) { jwe_t * jwe; jwk_t * jwk_pubkey_rsa, * jwk_privkey_rsa; unsigned char key[512]; size_t key_len = 0; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_generate_cypher_key(jwe), RHN_OK); memcpy(key, jwe->key, jwe->key_len); key_len = jwe->key_len; ck_assert_int_gt(key_len, 0); ck_assert_ptr_ne(key, NULL); ck_assert_int_eq(o_strlen((const char *)jwe->encrypted_key_b64url), 0); ck_assert_int_eq(r_jwe_encrypt_key(jwe, jwk_pubkey_rsa, 0), RHN_OK); ck_assert_int_gt(o_strlen((const char *)jwe->encrypted_key_b64url), 0); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_decrypt_key(jwe, jwk_privkey_rsa, 0), RHN_OK); ck_assert_int_gt(jwe->key_len, 0); ck_assert_ptr_ne(jwe->key, NULL); ck_assert_int_eq(jwe->key_len, key_len); ck_assert_int_eq(0, memcmp(jwe->key, key, key_len)); r_jwe_free(jwe); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_decrypt_updated_header_cbc) { jwe_t * jwe, * jwe_dec; jwk_t * jwk_pubkey_rsa, * jwk_privkey_rsa; char * token, header_b64[128] = {0}, * header_re, * token_updated; unsigned char header[256] = {0}, header_reb64[256] = {0}; size_t header_len = 0, header_reb64_len = 0; json_t * j_header = NULL; ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_dec), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, token = r_jwe_serialize(jwe, jwk_pubkey_rsa, 0)); o_strncpy(header_b64, token, o_strchr(token, '.')-token); ck_assert_int_ne(o_strlen(header_b64), 0); ck_assert_int_eq(o_base64url_decode((const unsigned char *)header_b64, o_strlen(header_b64), header, &header_len), 1); header[header_len] = '\0'; ck_assert_ptr_ne(NULL, j_header = json_loads((const char *)header, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(1, json_is_object(j_header)); ck_assert_int_eq(0, json_object_set_new(j_header, "plop", json_string("grut"))); ck_assert_ptr_ne(NULL, header_re = json_dumps(j_header, JSON_COMPACT)); ck_assert_int_eq(1, o_base64url_encode((const unsigned char *)header_re, o_strlen(header_re), header_reb64, &header_reb64_len)); token_updated = o_strndup((const char *)header_reb64, header_reb64_len); token_updated = mstrcatf(token_updated, "%s", o_strchr(token, '.')); ck_assert_int_eq(r_jwe_parse(jwe_dec, token_updated, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); o_free(token_updated); o_free(token); o_free(header_re); r_jwe_free(jwe); r_jwe_free(jwe_dec); json_decref(j_header); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_decrypt_updated_header_gcm) { jwe_t * jwe, * jwe_dec; jwk_t * jwk_pubkey_rsa, * jwk_privkey_rsa; char * token, header_b64[128] = {0}, * header_re, * token_updated; unsigned char header[256] = {0}, header_reb64[256] = {0}; size_t header_len = 0, header_reb64_len = 0; json_t * j_header = NULL; ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_dec), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, token = r_jwe_serialize(jwe, jwk_pubkey_rsa, 0)); o_strncpy(header_b64, token, o_strchr(token, '.')-token); ck_assert_int_ne(o_strlen(header_b64), 0); ck_assert_int_eq(o_base64url_decode((const unsigned char *)header_b64, o_strlen(header_b64), header, &header_len), 1); header[header_len] = '\0'; ck_assert_ptr_ne(NULL, j_header = json_loads((const char *)header, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(1, json_is_object(j_header)); ck_assert_int_eq(0, json_object_set_new(j_header, "plop", json_string("grut"))); ck_assert_ptr_ne(NULL, header_re = json_dumps(j_header, JSON_COMPACT)); ck_assert_int_eq(1, o_base64url_encode((const unsigned char *)header_re, o_strlen(header_re), header_reb64, &header_reb64_len)); token_updated = o_strndup((const char *)header_reb64, header_reb64_len); token_updated = mstrcatf(token_updated, "%s", o_strchr(token, '.')); ck_assert_int_eq(r_jwe_parse(jwe_dec, token_updated, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); o_free(token_updated); o_free(token); o_free(header_re); r_jwe_free(jwe); r_jwe_free(jwe_dec); json_decref(j_header); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); } END_TEST #if GNUTLS_VERSION_NUMBER >= 0x030600 && defined(R_WITH_CURL) static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)advanced_cert_pem_3); return U_CALLBACK_CONTINUE; } int callback_jku_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_response_properties(response, U_OPT_STATUS, 200, U_OPT_HEADER_PARAMETER, "Content-Type", "application/json", U_OPT_STRING_BODY, advanced_jku_4, U_OPT_NONE); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_advanced_parse) { jwk_t * jwk_pub; jwe_t * jwe; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, ADVANCED_TOKEN, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 4); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 0); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 1); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 1); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 1); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 1); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_X5U|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 2); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_advanced_parse(jwe, ADVANCED_TOKEN, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 4); r_jwe_free(jwe); r_jwk_free(jwk_pub); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_quick_parse) { jwk_t * jwk_pub; jwe_t * jwe; jwk_t * jwk; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); r_jwe_free(jwe); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_symmetric_str)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_OVERSIZE_IV, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_OVERSIZE_TAG, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_ENC, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_HEADER, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_HEADER_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_IV_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_TAG_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_DOTS, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_EMPTY_HEADER, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_EMPTY_IV, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_EMPTY_CIPHERTEXT, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwe = r_jwe_quick_parse(TOKEN_EMPTY_TAG, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(ADVANCED_TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 0); r_jwe_free(jwe); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(ADVANCED_TOKEN, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 4); r_jwe_free(jwe); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(ADVANCED_TOKEN, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), 2); r_jwe_free(jwe); r_jwk_free(jwk_pub); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_cipher_length) { jwe_t * jwe; jwk_t * jwk; ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_VALID_CIPHER_LEN_1, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_1, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_1_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_1_3, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_1_4, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_VALID_CIPHER_LEN_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_2_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_2_3, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_key_128_1)); ck_assert_ptr_ne(NULL, jwe = r_jwe_quick_parse(TOKEN_INVALID_CIPHER_LEN_2_4, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); r_jwk_free(jwk); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE core function tests"); tc_core = tcase_create("test_rhonabwy_core"); tcase_add_test(tc_core, test_rhonabwy_init); tcase_add_test(tc_core, test_rhonabwy_payload); tcase_add_test(tc_core, test_rhonabwy_alg); tcase_add_test(tc_core, test_rhonabwy_set_header); tcase_add_test(tc_core, test_rhonabwy_get_header); tcase_add_test(tc_core, test_rhonabwy_set_full_header_error); tcase_add_test(tc_core, test_rhonabwy_set_full_header); tcase_add_test(tc_core, test_rhonabwy_get_full_header); tcase_add_test(tc_core, test_rhonabwy_set_full_unprotected_header); tcase_add_test(tc_core, test_rhonabwy_get_full_unprotected_header); tcase_add_test(tc_core, test_rhonabwy_set_keys); tcase_add_test(tc_core, test_rhonabwy_set_jwks); tcase_add_test(tc_core, test_rhonabwy_add_keys_by_content); tcase_add_test(tc_core, test_rhonabwy_set_properties_error); tcase_add_test(tc_core, test_rhonabwy_set_properties); tcase_add_test(tc_core, test_rhonabwy_copy); tcase_add_test(tc_core, test_rhonabwy_generate_cypher_key); tcase_add_test(tc_core, test_rhonabwy_generate_iv); tcase_add_test(tc_core, test_rhonabwy_get_set_key_iv_aad); tcase_add_test(tc_core, test_rhonabwy_encrypt_payload_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_payload); tcase_add_test(tc_core, test_rhonabwy_encrypt_payload_all_format); tcase_add_test(tc_core, test_rhonabwy_decrypt_payload_invalid_key_no_tag); tcase_add_test(tc_core, test_rhonabwy_encrypt_payload_zip); tcase_add_test(tc_core, test_rhonabwy_encrypt_key_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_key_valid); #if GNUTLS_VERSION_NUMBER >= 0x030600 tcase_add_test(tc_core, test_rhonabwy_decrypt_key_invalid_encrypted_key); tcase_add_test(tc_core, test_rhonabwy_jwk_in_header_invalid); #endif tcase_add_test(tc_core, test_rhonabwy_decrypt_key_valid); tcase_add_test(tc_core, test_rhonabwy_decrypt_updated_header_cbc); tcase_add_test(tc_core, test_rhonabwy_decrypt_updated_header_gcm); #if GNUTLS_VERSION_NUMBER >= 0x030600 && defined(R_WITH_CURL) tcase_add_test(tc_core, test_rhonabwy_advanced_parse); tcase_add_test(tc_core, test_rhonabwy_quick_parse); tcase_add_test(tc_core, test_rhonabwy_cipher_length); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE core tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_dir.c000066400000000000000000000307621452472117100162100ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination..." #define TOKEN "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_HEADER "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_HEADER_B64 ";error;..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..;error;.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.;error-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.;error" #define TOKEN_INVALID_DOTS "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2IcxrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_IV "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE5ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8a4pm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" #define TOKEN_INVALID_TAG "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7x4gAA" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA4321" #define TOKEN_INVALID_ENC "eyJhbGciOiJkaXIiLCJlbmMiOiJBMTkyQ0JDLUhTMzg0In0..BE6ybfu_NcwhkB01q7svMw.W5WH8adpm8Rmgz5X8MNkG3MUH3-Pdjr7F3nJ2L0CHDupVFGRuoMWBmYFrIIK6Po23LTK7Xo0QtxgoemzYpclIHZ8WLEh3FD-Ku0bq5Vm2Ic.xrblYm4FGTv2j59L7xQgAA" const char jwk_key_128_1[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"Zd3bPKCfbPc2A6sh3M7dIbzgD6PS-qIwsbN79VgN5PY\"}"; const char jwk_key_128_2[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"ELG-YDhuRKg-6zH2QTR7Tug2zYz7v3coGLx_VWkcnVs\"}"; const char jwk_key_192_1[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"4-Jq38RkFa06N3L-fImTzgWgW3E2IDDAaPQm0eDn_kYAW4lT4NYHB-Qit5vepNn7\"}"; const char jwk_key_256_1[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"5CErcN-egEJlhCe8qCWhGRt2y99bFfBTiZUZcfPbO2ry2OSxri41Vm9nJUZvd6SNPBCJCIxOveW7sgV4AXoQMg\"}"; START_TEST(test_rhonabwy_encrypt_decrypt_ok) { jwe_t * jwe, * jwe_decrypt; char * token = NULL; size_t key_len = 0; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_ptr_ne(r_jwe_get_cypher_key(jwe, &key_len), NULL); ck_assert_int_eq(r_jwe_set_cypher_key(jwe_decrypt, r_jwe_get_cypher_key(jwe, NULL), key_len), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_with_jwk) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_privkey, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_OK); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_with_invalid_jwk) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_privkey_2; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_2, jwk_key_128_2), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_privkey, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey_2, 0), RHN_ERROR_INVALID); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk_privkey); r_jwk_free(jwk_privkey_2); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_with_jwk_invalid_key_size) { jwe_t * jwe; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk_privkey, 0), NULL); o_free(token); r_jwe_free(jwe); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_ok) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_OK); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_key_length) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_1, * jwk_2; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_2), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_1, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_2, jwk_key_256_1), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_1, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_DIR), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_2, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_1, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_2, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_2, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_1, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_1); r_jwk_free(jwk_2); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE dir key encryption tests"); tc_core = tcase_create("test_rhonabwy_dir"); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_with_jwk); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_with_invalid_jwk); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_with_jwk_invalid_key_size); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_ok); tcase_add_test(tc_core, test_rhonabwy_check_key_length); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE dir key encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_ecdh.c000066400000000000000000002137011452472117100163310ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination..." #if NETTLE_VERSION_NUMBER >= 0x030600 #define HUGE_DATA "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis efficitur lectus sit amet libero gravida eleifend. Nulla aliquam accumsan erat, quis tincidunt purus ultricies eu. Aenean eu dui ac diam placerat mollis. Duis eget tempor ipsum, vel ullamcorper purus. Ut eget quam vehicula, congue urna vel, dictum risus. Duis tristique est sed diam lobortis commodo. Proin et urna in odio malesuada sagittis. Donec lectus ligula, porttitor sed lorem ut, malesuada posuere neque. Nullam et nisl a felis congue mattis id non lectus.\ Quisque viverra hendrerit malesuada. Integer sollicitudin magna purus, in dignissim eros ullamcorper et. Praesent dignissim metus neque, eget tempor dolor tincidunt egestas. Nulla odio risus, tincidunt et egestas aliquet, pellentesque et eros. Etiam mattis orci a dui efficitur pharetra. Donec fermentum sem sed lacus finibus, nec luctus nisl vulputate. Donec sodales, nisi sed posuere maximus, lectus elit fermentum sapien, quis volutpat risus nisl vel dui. In vitae ante diam.\ Vivamus a nisl quam. Proin in lectus nunc. Aliquam condimentum tellus non feugiat aliquam. Nulla eu mi ligula. Proin auctor varius massa sed consectetur. Nulla et ligula pellentesque, egestas dui eu, gravida arcu. Maecenas vehicula feugiat tincidunt. Aenean sed sollicitudin ex. Cras luctus facilisis erat eu pharetra. Vestibulum interdum consequat tellus nec sagittis. Aliquam tincidunt eget lectus non bibendum. Mauris ut consectetur diam.\ Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed lorem lectus, ullamcorper consectetur quam ut, pharetra consectetur diam. Suspendisse eu erat quis nunc imperdiet lacinia vitae id arcu. Fusce non euismod urna. Aenean lacinia porta tellus nec rutrum. Aliquam est magna, aliquam non hendrerit eget, scelerisque quis sapien. Quisque consectetur et lacus non dapibus. Duis diam purus, vulputate convallis faucibus in, rutrum quis mi. Sed sed magna eget tellus semper suscipit a in augue.\ Aenean vitae tortor quam. Praesent pulvinar nulla a nisi egestas, laoreet tempus mauris ullamcorper. Nam vulputate molestie velit, quis laoreet felis suscipit euismod. Pellentesque a enim dapibus, tincidunt lorem vel, suscipit turpis. Phasellus id metus vehicula, luctus sem nec, maximus purus. Duis dictum elit quam, quis rhoncus ex ullamcorper ut. Donec fringilla augue vitae vestibulum maximus. Mauris vel arcu eget arcu bibendum ornare." #define TOKEN "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_HEADER "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMgo.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_DOTS "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER_KEY "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.IEru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER_KEY_SMALL "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER_KEY_LARGE "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GAed.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_IV "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPEQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FEbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_TAG "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PE8wi2GGHqzww" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGH" #define TOKEN_INVALID_HEADER_B64 ";error;.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER_KEY_B64 "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.;error;.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.;error;.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.;error;.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.;error;" #define TOKEN_OVERSIZE_APU "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eUNnIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19Cg.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_OVERSIZE_APV "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlDZyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19Cg.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_OVERSIZE_MISSING_EPK "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGt1Ijp7Imt0eSI6IkVDIiwieCI6IkFNd3JtNmp6aF9ndzNWZm9MWTROM0ppLUlOeWlPTTRGWG5yRzg4ajlHaHVhIiwieSI6IlJSTlBVd3ZYQ0VFd01YZjhJTnFvRmJ2MFh6WjU1RkhDd3RFeXBoUXhSMDAiLCJjcnYiOiJQLTI1NiJ9fQo.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_OVERSIZE_INVALID_EPK "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiY0d4dmNBbyIsInkiOiJaM0oxZEFvIiwiY3J2IjoiUC0yNTYifX0K.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_ENC "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExOTJDQkMtSFMzODQiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_APU "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiI7ZXJyb3I7IiwiYXB2IjoiWjNKMWRBbyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" #define TOKEN_INVALID_APV "eyJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJhcHUiOiJjR3h2Y0FvIiwiYXB2IjoiO2Vycm9yOyIsImtpZCI6IjEiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiQU13cm02anpoX2d3M1Zmb0xZNE4zSmktSU55aU9NNEZYbnJHODhqOUdodWEiLCJ5IjoiUlJOUFV3dlhDRUV3TVhmOElOcW9GYnYwWHpaNTVGSEN3dEV5cGhReFIwMCIsImNydiI6IlAtMjU2In19.Izru9wTpv5FPlPp7jpDZkueMZ3luMjXBaI2s0YgUtMiDPBAgXw8_GA.aKgPGQYvpPwHsQiDOeTFoQ.3syjxFimN-u5zY8t-mwIcZwVshIfYbzcxXID7FTbqdAKPWKlWfOdkXpk6V_u5p25U73Izv9qgr1UaWQAzaLli-LqFXptmCyciipYJc2BRhw.OwcQLpd3_PZ8wi2GGHqzww" const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_small_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"cGxvcAo\","\ "\"y\":\"Z3J1dAo\",\"d\":\"Y29pbgo\","\ "\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_large_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"cz-Y7wdU6n3j6QB5J-KtVg1ozfir1yuRsWBMZ2NvZytGRj0V-41c92HxrsOC-Ia--0sK_ATpnRKlgS5jo286c6o\","\ "\"y\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"d\":\"Aen_lIXMdZhFBSkgPdXGsyNTh6XEDDk74-08nawnxO1YblVM-Rp7FbumjBbCpA7jPxRxKO1h3VJFP93uvqw16RIE\","\ "\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_pubkey_ecdsa_small_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"cGxvcAo\","\ "\"y\":\"Z3J1dAo\",\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_pubkey_ecdsa_large_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"cz-Y7wdU6n3j6QB5J-KtVg1ozfir1yuRsWBMZ2NvZytGRj0V-41c92HxrsOC-Ia--0sK_ATpnRKlgS5jo286c6o\","\ "\"y\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_p384_str[] = "{\"alg\":\"ES512\",\"crv\":\"P-384\",\"d\":\"IKRyzFYbvLo4JoBMlPPTdIE8mLlcCO03XLh-97aNT3sQ9cT4vb3nSjWCecTUvjW6\","\ "\"kty\":\"EC\",\"x\":\"Nx2Wxf0o6A01m6ymiD7YIfmWkyBrySWzq5N85bMUs_9G8D_l4RRxLj4i7z1_5Rvo\","\ "\"y\":\"c4iG6Gp5vEcoyuGREu40AejY-fkg0K_iYEic1sME-VphV8L94IWJU3EbhA_zEQhb\"}"; const char jwk_pubkey_ecdsa_p384_str[] = "{\"alg\":\"ES512\",\"crv\":\"P-384\",\"kty\":\"EC\","\ "\"x\":\"Nx2Wxf0o6A01m6ymiD7YIfmWkyBrySWzq5N85bMUs_9G8D_l4RRxLj4i7z1_5Rvo\","\ "\"y\":\"c4iG6Gp5vEcoyuGREu40AejY-fkg0K_iYEic1sME-VphV8L94IWJU3EbhA_zEQhb\"}"; const char jwk_privkey_ecdsa_p521_str[] = "{\"alg\":\"ES512\",\"crv\":\"P-521\",\"d\":\"cz-Y7wdU6n3j6QB5J-KtVg1ozfir1yuRsWBMZ2NvZytGRj0V-41c92HxrsOC-Ia--0sK_ATpnRKlgS5jo286c6o\","\ "\"kty\":\"EC\",\"x\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"y\":\"Aen_lIXMdZhFBSkgPdXGsyNTh6XEDDk74-08nawnxO1YblVM-Rp7FbumjBbCpA7jPxRxKO1h3VJFP93uvqw16RIE\"}"; const char jwk_pubkey_ecdsa_p521_str[] = "{\"alg\":\"ES512\",\"crv\":\"P-521\",\"kty\":\"EC\","\ "\"x\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"y\":\"Aen_lIXMdZhFBSkgPdXGsyNTh6XEDDk74-08nawnxO1YblVM-Rp7FbumjBbCpA7jPxRxKO1h3VJFP93uvqw16RIE\"}"; const char jwk_pubkey_ecdsa_str_2[] = "{\"kty\":\"EC\",\"x\":\"RKL0w34ppc4wuBuzotuWo9d6hGv59uWjgc5oimWQtYU\",\"y\":\"S8EabLKBmyT2v_vPSrpfWnYw6edRm9I60UQlbvSS1eU\","\ "\"crv\":\"P-256\",\"kid\":\"2\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_str_2[] = "{\"kty\":\"EC\",\"x\":\"RKL0w34ppc4wuBuzotuWo9d6hGv59uWjgc5oimWQtYU\",\"y\":\"S8EabLKBmyT2v_vPSrpfWnYw6edRm9I60UQlbvSS1eU\""\ ",\"d\":\"KMRJaGpxVer0w9lMjIY_UrjC067tZdEJkL5eaiBVWi8\",\"crv\":\"P-256\",\"kid\":\"2\",\"alg\":\"ES256\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_x25519_str[] = "{\"kty\":\"OKP\",\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"AuQ7nbIvxilE4nzzRoS_C_cmpqMx-kcXNkcAyy46fWM\"}"; const char jwk_privkey_x25519_str[] = "{\"kty\":\"OKP\",\"d\":\"-NOCJItqI-R-AFsq1cLNLAIpfIf-otm7x2psH5EXJoo\"," "\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"AuQ7nbIvxilE4nzzRoS_C_cmpqMx-kcXNkcAyy46fWM\"}"; const char jwk_pubkey_x25519_small_str[] = "{\"kty\":\"OKP\",\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"cGxvcAo\"}"; const char jwk_privkey_x25519_small_str[] = "{\"kty\":\"OKP\",\"d\":\"Y29pbgo\",\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"cGxvcAo\"}"; const char jwk_pubkey_x25519_large_str[] = "{\"kty\":\"OKP\",\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\"}"; const char jwk_privkey_x25519_large_str[] = "{\"kty\":\"OKP\",\"d\":\"DFFZ-8-3Q7xEBHV0VVC1JmBL4oMrRo9zDKqLIJF1GEJgNGgrBYY5CrsoZbgs6NOurHTp73o6jhM\"," "\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\"}"; const char jwk_privkey_x25519_str_2[] = "{\"kty\":\"OKP\",\"d\":\"kcIdGcJVDgzC6KLd9I1P7of4RJvXxZZmilCh_f-0K8Q\"," "\"use\":\"enc\",\"crv\":\"X25519\",\"x\":\"JIrudOxnjSYGNO6Jsa7Bp00juLU10XB6ZutgPgpfEyE\"}"; const char jwk_pubkey_x448_str[] = "{\"kty\":\"OKP\",\"use\":\"enc\",\"crv\":\"X448\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\"}"; const char jwk_privkey_x448_str[] = "{\"kty\":\"OKP\",\"d\":\"DFFZ-8-3Q7xEBHV0VVC1JmBL4oMrRo9zDKqLIJF1GEJgNGgrBYY5CrsoZbgs6NOurHTp73o6jhM\"," "\"use\":\"enc\",\"crv\":\"X448\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\"}"; const char jwk_privkey_x448_str_2[] = "{\"kty\":\"OKP\",\"d\":\"k_-0MeUxtYskqQkpSxWCKMhLCVfDbhW5pMysvAF84v7C9RI9cm5imhkAMs3ngjXAqUlAnwmQtRI\"," "\"use\":\"enc\",\"crv\":\"X448\",\"x\":\"sXZMHweV1nAKE5sZ-z8Sp-Sbd0dYXbzqpjGMwPHORP1K1gsKLaQvLSmy4yStLRVPGoTCW8IPqyw\"}"; static void test_encrypt_decrypt_ok(jwa_alg alg, jwa_enc enc) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test alg %s, enc %s", r_jwa_alg_to_str(alg), r_jwa_enc_to_str(enc)); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, alg), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, enc), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } static void test_decrypt_invalid_key(jwa_alg alg, jwa_enc enc) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test invalid key alg %s, enc %s", r_jwa_alg_to_str(alg), r_jwa_enc_to_str(enc)); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, alg), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, enc), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } START_TEST(test_rhonabwy_encrypt_decrypt_ok) { test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A128CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A192CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A256CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A128GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A192GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A256GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A128CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A192CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A256CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A128GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A192GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A256GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A128CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A192CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A256CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A128GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A192GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A256GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A128CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A192CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A256CBC); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A128GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A192GCM); test_encrypt_decrypt_ok(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A256GCM); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_x25519_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test X25519"); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_x448_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test X25519"); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_invalid_parameters) { jwe_t * jwe; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", ";not a base64;"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", ";not a base64;"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", ";not a base64;"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", ";not a base64;"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", ";not a base64;"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", ";not a base64;"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", NULL), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_decrypt_invalid_key) { test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A128CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A192CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A256CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A128GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A192GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES, R_JWA_ENC_A256GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A128CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A192CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A256CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A128GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A192GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A128KW, R_JWA_ENC_A256GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A128CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A192CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A256CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A128GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A192GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A192KW, R_JWA_ENC_A256GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A128CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A192CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A256CBC); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A128GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A192GCM); test_decrypt_invalid_key(R_JWA_ALG_ECDH_ES_A256KW, R_JWA_ENC_A256GCM); } END_TEST START_TEST(test_rhonabwy_decrypt_invalid_x25519_key) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test invalid key X25519"); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_x25519_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_invalid_x448_key) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; y_log_message(Y_LOG_LEVEL_DEBUG, "Test invalid key X25519"); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_x448_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_invalid_key_type) { jwe_t * jwe; jwk_t * jwk_pubkey, * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_p521_str), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk_pubkey, 0), NULL); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_p521_str), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk_pubkey, 0), NULL); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk_pubkey, 0), NULL); r_jwk_free(jwk_pubkey); r_jwk_free(jwk_privkey); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_KEY_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_OVERSIZE_APU, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_OVERSIZE_APV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_OVERSIZE_MISSING_EPK, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_OVERSIZE_INVALID_EPK, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_APU, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_APV, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_KEY_SMALL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_KEY_LARGE, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_key_length_ecdh_es) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk1_pub, * jwk1_priv, * jwk2_pub, * jwk2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_pub, jwk_pubkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_priv, jwk_privkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk2_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk2_pub); r_jwk_free(jwk2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_length_ecdh_es_a256kw) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk1_pub, * jwk1_priv, * jwk2_pub, * jwk2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_pub, jwk_pubkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_priv, jwk_privkey_x448_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_ECDH_ES_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk2_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk2_pub); r_jwk_free(jwk2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_type_ecdh_es) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk1_pub, * jwk1_priv, * jwk2_pub, * jwk2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_priv, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk2_priv, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk2_pub); r_jwk_free(jwk2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_type_ecdh_es_a256kw) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk1_pub, * jwk1_priv, * jwk2_pub, * jwk2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_priv, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_ECDH_ES_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk2_priv, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk2_pub); r_jwk_free(jwk2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_length_ecdh_es_ecdsa) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk1_pub, * jwk1_priv, * jwk2_pub, * jwk2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_pub, jwk_pubkey_ecdsa_p384_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_priv, jwk_privkey_ecdsa_p384_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk2_priv, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk1_priv, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_dec_2); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk2_pub); r_jwk_free(jwk2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_length_invalid_ecddsa_key) { jwe_t * jwe_enc_1, * jwe_dec; jwk_t * jwk1_pub, * jwk1_priv, * jwk1_invalid_pub, * jwk1_invalid_priv, * jwk2_invalid_pub, * jwk2_invalid_priv; char * token; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_invalid_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_invalid_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_invalid_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_invalid_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_invalid_pub, jwk_pubkey_ecdsa_small_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_invalid_priv, jwk_privkey_ecdsa_small_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_invalid_pub, jwk_pubkey_ecdsa_large_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_invalid_priv, jwk_privkey_ecdsa_large_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk1_invalid_pub, 0), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk2_invalid_pub, 0), NULL); ck_assert_ptr_ne((token = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk1_invalid_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk2_invalid_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk1_invalid_pub); r_jwk_free(jwk1_invalid_priv); r_jwk_free(jwk2_invalid_pub); r_jwk_free(jwk2_invalid_priv); r_jwe_free(jwe_enc_1); r_free(token); } END_TEST START_TEST(test_rhonabwy_check_key_length_invalid_eddsa_key) { jwe_t * jwe_enc_1, * jwe_dec; jwk_t * jwk1_pub, * jwk1_priv, * jwk1_invalid_pub, * jwk1_invalid_priv, * jwk2_invalid_pub, * jwk2_invalid_priv; char * token; ck_assert_int_eq(r_jwk_init(&jwk1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_invalid_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk1_invalid_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_invalid_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2_invalid_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_pub, jwk_pubkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_priv, jwk_privkey_x25519_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_invalid_pub, jwk_pubkey_x25519_small_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1_invalid_priv, jwk_privkey_x25519_small_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_invalid_pub, jwk_pubkey_x25519_large_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2_invalid_priv, jwk_privkey_x25519_large_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk1_invalid_pub, 0), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk2_invalid_pub, 0), NULL); ck_assert_ptr_ne((token = r_jwe_serialize(jwe_enc_1, jwk1_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk1_priv, 0), RHN_OK); r_jwe_free(jwe_dec); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk1_invalid_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec); ck_assert_ptr_ne((jwe_dec = r_jwe_quick_parse(token, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec, jwk2_invalid_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec); r_jwk_free(jwk1_pub); r_jwk_free(jwk1_priv); r_jwk_free(jwk1_invalid_pub); r_jwk_free(jwk1_invalid_priv); r_jwk_free(jwk2_invalid_pub); r_jwk_free(jwk2_invalid_priv); r_jwe_free(jwe_enc_1); r_free(token); } END_TEST START_TEST(test_rhonabwy_check_apu) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; struct _o_datum apv = {0, NULL}, apu = {0, NULL}; ck_assert_int_eq(o_base64url_encode_alloc((const unsigned char *)HUGE_DATA, o_strlen(HUGE_DATA)-20, &apu), 1); apu.data[apu.size] = '\0'; ck_assert_int_eq(o_base64url_encode_alloc((const unsigned char *)HUGE_DATA, o_strlen(HUGE_DATA), &apv), 1); apv.data[apv.size] = '\0'; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", (const char *)apu.data), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "apu", 42), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_ERROR_PARAM); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", ""), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_ERROR_PARAM); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", ";error;"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Z3J1dAo"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); o_free(apu.data); o_free(apv.data); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_apv) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; struct _o_datum apv = {0, NULL}, apu = {0, NULL}; ck_assert_int_eq(o_base64url_encode_alloc((const unsigned char *)HUGE_DATA, o_strlen(HUGE_DATA)-20, &apu), 1); apu.data[apu.size] = '\0'; ck_assert_int_eq(o_base64url_encode_alloc((const unsigned char *)HUGE_DATA, o_strlen(HUGE_DATA), &apv), 1); apv.data[apv.size] = '\0'; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", (const char *)apu.data), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "apv", 42), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_ERROR_PARAM); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", ""), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_ERROR_PARAM); o_free(token); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", ";error;"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "cGxvcAo"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, NULL, 0), NULL); o_free(apu.data); o_free(apv.data); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_rfc_ok) { const char eph[] = " {\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0\",\"y\":\"SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps\",\"d\":\"0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo\"}", bob[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"weNJy2HscCSM6AEDTDg04biOvhFhyyWvOHQfeF_PxMQ\",\"y\":\"e8lnCO-AlStT-NJVX-crhB7QRYhiix03illJOVAOyck\"}"; jwk_t * jwk_eph, * jwk_bob; jwe_t * jwe; char * token; unsigned char expected_key[] = {86, 170, 141, 234, 248, 35, 109, 32, 92, 34, 40, 205, 113, 167, 16, 26}; ck_assert_int_eq(r_jwk_init(&jwk_eph), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_bob), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_eph, eph), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_bob, bob), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_eph, jwk_bob), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apu", "QWxpY2U"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "apv", "Qm9i"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(sizeof(expected_key), jwe->key_len); ck_assert_int_eq(0, memcmp(jwe->key, expected_key, jwe->key_len)); r_jwk_free(jwk_eph); r_jwk_free(jwk_bob); r_jwe_free(jwe); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE ECDH-ES encryption tests"); tc_core = tcase_create("test_rhonabwy_ecdh_es"); #if NETTLE_VERSION_NUMBER >= 0x030600 tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_x25519_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_x448_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_invalid_parameters); tcase_add_test(tc_core, test_rhonabwy_decrypt_invalid_key); tcase_add_test(tc_core, test_rhonabwy_decrypt_invalid_x25519_key); tcase_add_test(tc_core, test_rhonabwy_decrypt_invalid_x448_key); tcase_add_test(tc_core, test_rhonabwy_encrypt_invalid_key_type); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_check_key_length_ecdh_es); tcase_add_test(tc_core, test_rhonabwy_check_key_length_ecdh_es_a256kw); tcase_add_test(tc_core, test_rhonabwy_check_key_type_ecdh_es); tcase_add_test(tc_core, test_rhonabwy_check_key_type_ecdh_es_a256kw); tcase_add_test(tc_core, test_rhonabwy_check_key_length_ecdh_es_ecdsa); tcase_add_test(tc_core, test_rhonabwy_check_key_length_invalid_ecddsa_key); tcase_add_test(tc_core, test_rhonabwy_check_key_length_invalid_eddsa_key); tcase_add_test(tc_core, test_rhonabwy_check_apu); tcase_add_test(tc_core, test_rhonabwy_check_apv); tcase_add_test(tc_core, test_rhonabwy_rfc_ok); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE ECDH-ES encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_json.c000066400000000000000000001662171452472117100164100ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define KID_1 "Raoul" #define KID_2 "Ernie" #define KID_3 "Sammy" const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"kid\":\""KID_1"\",\"alg\":\"RSA1_5\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"kid\":\""KID_1"\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":" "\""KID_2"\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"A128KW\",\"k\":\"AAECAwQFBgcICQoLDA0ODw\",\"kid\":\""KID_2"\"}"; const char jwk_key_aesgcm[] = "{\"kty\":\"oct\",\"alg\":\"A128GCMKW\",\"k\":\"ELG-YDhuRKg-6zH2QTR7Tg\",\"kid\":\""KID_3"\"}"; const char jwks_all_privkeys[] = "{\"keys\": [" "{\"kty\": \"RSA\", \"n\": \"AL9GIadpvuz-_1Xr2xAaZJwhxPqQ_xfanlYta3rg2cgBAryHUtWXlFP_FCGpYoX3kOlnDFpeczdc19Kt5K6YSaC9pTpBa_hT7iAzj8sx-YIx7JbAHXCnjM1LbsTA4_0T--Fv3xC4RtBktH4gjUwe3FDwyr87DyDt6d13wFBLvKKkggO70StGFRQucLY_ZXnSJIzJLdIpZ6H-0FFpaOw2kyS6zT1zxw71i1UtQodauFZvWuGIj6eDRakMJBaIkf59ZMXdgzcGuWea38JjpP6jU26q3PHXXUfdrL7QY0rzOROuoEDkeSyVdxAwFd3VdKhzWMJCLBDWg_yOuqr7fW3dzcU\", \"e\": \"AQAB\", \"d\": \"AKCnAftAGSmrn8CGAg_LazesMWsXP_rEF3tgWMbzdlfDaY35xzw5PU8zjrAbOfI1llRDxh9c9z7Hz0pX3hw7MpQ81TtR2aLQs8_-HsdXKS8OSZ3wrImDYQLJWbcOIC_fig62TNAZRvkfrG3HX4ZQ4VFmfZQSwckxqtzmCPQoOL8NI5x1LolCH9j5FCFLhyePoI6K0fR8OzLmD6CMvFFW-IfrxwdtJn2IlioWIhDUs_OtDIKzSoducYGziPA45OEloT_TcLiseeP_JycOn0aoQTsjpNWBaEtqq8KKHdx3JX4kWLEIE5h8jXaRttwCvdca0FlggfkppUQeWpSQSHdAQaE\", \"p\": \"ANrbmia58Rf3KNyl76GafjR9LFJhdJJFGSwPiRhW0NdPoAuJvklj2rBJu33XKYZ-slZQfZwDswXl1XSzC06IVuCn7znAiEy42m0UKJOZxqx7rDICzCzoYTdAsL29iC4zmXg6zJbYYEaWhdkYVsIanRbDxPGsNsPgqFJ1BGi_vJiN\", \"q\": \"AN-8IgrjQOIRoLjRGH0uQuIHZwSVfPvzEEb0u5MVjBWWa5-7ZoMtI6WeV1_pWdC10zz7MTP3L_ruUQTve2Xp_R0EZlHtOyFe-QYGPNyQn3evwUX-T5tflrFl20wr-c1Czy6ctWbZYrv6cXMpxEhU9JG3WPNgtusdj-Zp5o57CIgZ\", \"qi\": \"AKmHBufGZQ8oarF0w7MwXpBdg9PSIevH9ONrUkWc1ljdSTKRJD2nMqrZqPW32XKnK7bVX6aVV8T3DFLo7BbEmcUnY7inkcNjL_WMU6Zwm1MXsFbjc0yE4rbOLca24YQ4awCXzKOxYjeGcayq7B6BZ23NWVWuEC_ha22YgchfyfMH\", \"dp\": \"PFShD9_eGC8n8ntDrZa7B5kh6Ku4yMGHiN_XeQAlndTzV3rnG7ANDt-kcbIoXkz6uFSD68gRR6TtzLe2fDWVTWS9y3vJluy2Oa9-6AFSBSYqd7bRtedxNRv-HK_spF_RBJWg5ExNbef8ibXt5KAVgbsBxWUly6VYgTKEvqNsR9k\", \"dq\": \"FLVjKULTlJkxGSoxbBTGGAm7XU9A3EkpLogkfH64Ep9zortDx8x7yi6Xw8bji0_pF3HgogC1LjK0yRIph8tapD7uAZNFr9cMkaQuKfQw7nEUIJhjYew9FHprC-feHUObzaKvn69rVh7eNVyeUFucr4ga8Zv4ElcQJLGUp4d3yLE\", \"kid\": \"RSA1_5\", \"alg\": \"RSA1_5\"}" #if NETTLE_VERSION_NUMBER >= 0x030400 ",{\"kty\": \"RSA\", \"n\": \"ALup-Z784fSG10vOGotny1I5G79Mw-MI8eXZmE1sR6d-1APlI3xDY6RBzjYHsmwyKL_Dxp6mkLkyzoom2c2flNwIDGyxXS9zMpBG84kE8jKiMP_N7tG0NkqZ45zJTDBg7VG1kxtcBZj5wuThPPy8SkbcQay9dH7-9u-6n-5suqMWG88YEbPugHbsiAhJ6hopKKX2-8VLJ7w0IMLXAlGXdaLz_6wh5S0KwwpMe0xEyiNCkWWFu9uNyuuR0UZPCZTQSTJssUUgCovnCKV_oS399G7M1k7qzOx0Y7EINvrcuxmpcLm9buAiDSlcn2DHRQNjAt3C3X7agLuquKl-NrG0-OU\", \"e\": \"AQAB\", \"d\": \"WenOl8ZB3I7eiItvXGuWlwaVrMpy8ExQ2fevaSkAC9hQbK1Umy0OiJye2HRHoF9H9tkuSMU1ggY9vyNuJ37WK7YPfeRc6WcgStAzzup3wJrFL0rTqdXWTVf-Hhi0UFmgWw3MNceZRvojztW8CruMOvc84C7FqjMuzR11kx61LX2QD-O3BhrFO7Efqhns3h-5qpCXYklJ0ToCQGatsQYNbXOfU9zTkmTeMmWRLmU0_wV6gLwsG6sjRfEYDwLiLUYnuvB834uqsDnlrecgLdK9DQ1n5IAGmRzp4B0A54PJhc9zw34lUlGcqHOnmkOLbPXP-nyurfQ2CwXTWmot3MD94Q\", \"p\": \"ANJs_no_UeTaA5gVBkj4fl5iSu0Kx7tM39bbelCChlKkB89AoMTm9nd3uZjnY1O6Z00MOcgaWj2cM9tWAmA4fpWcEqY6NeooeQNB1_l0Cp_k7Tn_Ig6IyVXAO12tDWhSzumVQNJI6qJQy-vGcQXMMZ_XTUxhCmCrsCb8ziVKAdhb\", \"q\": \"AORO9XeL8mn9ph8lNkRiVLKR2yHyJJ8HAbAnVpRD6njdpn35ZUfOIXclwFDIwApuYVpX8BQr-jrLUfnZ520HM1UBUMhzIurftRDewbHcXUtHU3ivNLpFYEjcdbPk9VcA1DA918llIkshe1-MKGn_as7WF09qXHPQnaO9RkYt2ze_\", \"qi\": \"HVi7B53n44UC0ny-NFDfRGvM6EyMAZTw4YjWzzQq0WvC25mpWLHsr-fuzijONFO745jh_gMtAU4xofjWL3BmYToQHymzLAJN6QnrgHWXd8a3d3zUoPMVEsIM5YDr_V_Cmg5-kxRQIpmK85LjtLinex0H4_3A8Gt0LpXE9elIHpg\", \"dp\": \"AI8MGVLxiLKSoq7YXBVvGDkBiP3rvivN7r0ZJuVkVfwIFmcGAETa3eIJOdqAMj3REjiGfyFRCNepQHdy2NqgjS0XlHX8THqKWPml4TRrdm2MKtiqYHSQ-I2ayMC9y8eHw7F3DUHm39rIIlh95oeScInAy4OI1I0zKeTXJyyiSu7R\", \"dq\": \"ANfNVrLgQowzKOIJr4jmFT8RJTuqATmcStkx5eGRbMFAac5rfXNpATL5KRZzGysA-N6HfrPiec03QE5VzS2-f6Pa8Xv3cMroF-NRW27-Z-TvD5RksAdd6kwUruETC2BotSjAXAbOpKK1jENdXRoMRu4pabE0TR1f1JHgJ9vQHoVL\", \"kid\": \"RSA-OAEP\", \"alg\": \"RSA-OAEP\"}" ",{\"kty\": \"RSA\", \"n\": \"ANZKK6hNe1e9TwmRuT5Espfu7fslRrE1UmtSv1Xka1u9D75Wqt1flKqCThPaiqPpjbG8LX2zPk_f74vPFK6RvetgOVZOH3hJ3b5du051Dbcdiv_AVM3iWJSCqZyViVOb02Kh7EpXEAnvn2dfQW4ev23QoFx40rBwCW-quO139zoOEDc6WlJdn_DwmrpN0SadZmiMKyJvZlIo6p0BDbWAfj_PG7bGE_CwMmaxIg3rF_zUI2U4K1SQh45Fv2Dtgl_WZlJCEK0qOx2lmzN1wZLZk7M6bt9zW8OGYwHNY1gLSrdBkC_FN7ecbzApJ4QLkSJG1vKvpxLbqSXxPS1DXdGuNrs\", \"e\": \"AQAB\", \"d\": \"GAeHL79IhoU2-La7lAz2De2ACDqc28BD9r73r7UGiOoBevGTBXHzZM9p2_YUt963wed9HmxcH27YGNBm3FCBgIRwyYnHI6D82Zz_JQQhPph0fstddxzbnAOu610lYhfGM3g-2_M5XDPfpyLaXnPaOYE8ikIONjTKChiV1iMuuPaoMZFuaatSaInIDOkhRJfgsFbE3l_z2Z5QwxkWFMWC14a8zRRfElTEGmyWXmoWEMI9xea7Zqtl1XS99PBvJUdNdaPc74lUgh1TDncBU1R6CjoOs5DdzUfRYHN1F2BqfKh7YlnxDKNVPssNsbBFZNsLHVeakYjGws4G6FcRVCudQQ\", \"p\": \"APJdeDaLUa0A-rbr2gtMevJcU7biLHT_77NtsE7VlruMVDovoY7KCoIaB4CyGTP_Y1GwQBc-aHs9OGhIYG2VZWK3ImILIvHbTQ4orvMz3eFlq428kaO4tQ0w_zjmgxegb2efP6a7yML5_MXtpZLT4rtOUASvZyq1im57lJHQVLHb\", \"q\": \"AOJYXFGU5Nyc-ksaG1syreL9FhmSRL8I7PL_vI176r_X5Zpd9koMAR1TSr90rQ26MvgW-eoG8NFP0BYj7ay_5-ENTPJ6GUJhmTK5HzlNQlz35XIzcXgC0akhfPtsJlqN4w1CjOcKPC5HpmPcWP9G9L4Y-ZtP74UJk7gkrEP3s9Sh\", \"qi\": \"AKnu_rJQcJ7vWC1vkzbxeXYva94KQj8Pay58XBABtTK-zuXKwVlwuYltSNaw_PAUvBL-hqx2KTF4z7ktGKCiMcQoCHtDYfQTTcm76Fu3id2i7ymReIu7o4FG_Eau2eYJwVU_Z73JfxPIEM-3ncqQz520R4JFNoW_ewUdIRteSVdd\", \"dp\": \"AOYcBnnK9uYKKwAnl6Lon0aikDzwKoN_SAcUmrOOqQkyJ_oCpSJcA3QY4Iy5C6LJ1HOHoqIu96Yirv6b0SnaESOTesqZhjkZHOTXjZuM4BoTnLj6k1Bdm1CF95v_h_GTupIoqZdVbTxpeyw1AOIR2JA7v09jddEgAen53UpAAVnH\", \"dq\": \"HomhWvhlsEYVltBc5H7_6uIOe0C6ubNwlJBgVg5j66IrPhpzQiZAeD5mlVIejv2SJtqiuSpaj0LfZj1OscHqfPiYaxaCFeypCKjlR4ve6kAf2rqKEpD-zHzSKfG7cvg1q_JQpFNDL1NHZa2y7C4ckxE3i_bK7_4MyglYnIrs3kE\", \"kid\": \"RSA-OAEP-256\", \"alg\": \"RSA-OAEP-256\"}" ",{\"kty\": \"oct\", \"k\": \"wihT-v_265OXyGpOIe62hg\", \"alg\": \"A128KW\", \"kid\": \"A128KW\"}" ",{\"kty\": \"oct\", \"k\": \"OI_6XYApCCn_9R-8GPxOubBPkMNbt3Vd\", \"alg\": \"A192KW\", \"kid\": \"A192KW\"}" ",{\"kty\": \"oct\", \"k\": \"IZ2ifICT03pMCZfqHCtO1vPU1_yhGwZUu3Lt3NPiiow\", \"alg\": \"A256KW\", \"kid\": \"A256KW\"}" #endif #if NETTLE_VERSION_NUMBER >= 0x030600 ",{\"kty\": \"EC\", \"x\": \"AOJ9FiyptD67tbjYKAXr7sn7TzT5SAtcke5YcZjXbdLy\", \"y\": \"AMSB2nGzT4mCbai0hY_qODr4DaHVD9Gk_oJ9lXGb-TRw\", \"d\": \"esY6_Xtac52F88CHCIAs-b8kG7VYBvN8GV5vTVeUB6Y\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A128KW\", \"alg\": \"ECDH-ES+A128KW\"}" ",{\"kty\": \"EC\", \"x\": \"dQQcQ_TdYVScUzDaMdHUHvGZtfc_piecctF-q4Mz8PQ\", \"y\": \"AND5hLGPJKeEFDl_AQ9JsR5cE-uFUgvLQgPW9BgrluZJ\", \"d\": \"FEmyk5hggKjbm-KAAutCvy4Wp4zOYaux8u5Jt6hks-k\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A192KW\", \"alg\": \"ECDH-ES+A192KW\"}" ",{\"kty\": \"EC\", \"x\": \"AP4C-BLKoo98wrpMSuovvkhV2A7eyXwAw4DSa-Bs724I\", \"y\": \"djnAg_Fqjf9C23WsAI_c7ktV3XweOrfBA5lKzHjV4tw\", \"d\": \"c6-ZFaSrXFhxi0GVjD1DNagk_hwsg7x8BEoh0eT6LmU\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A256KW\", \"alg\": \"ECDH-ES+A256KW\"}" ",{\"kty\": \"OKP\", \"x\": \"AuQ7nbIvxilE4nzzRoS_C_cmpqMx-kcXNkcAyy46fWM\", \"d\": \"-NOCJItqI-R-AFsq1cLNLAIpfIf-otm7x2psH5EXJoo\", \"crv\": \"X25519\", \"kid\": \"ECDH-ES+A256KW-X25519\", \"alg\": \"ECDH-ES+A256KW\"}" ",{\"kty\":\"OKP\",\"d\":\"DFFZ-8-3Q7xEBHV0VVC1JmBL4oMrRo9zDKqLIJF1GEJgNGgrBYY5CrsoZbgs6NOurHTp73o6jhM\",\"crv\":\"X448\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\", \"kid\": \"ECDH-ES+A128KW-X448\", \"alg\": \"ECDH-ES+A128KW\"}" #endif ",{\"kty\": \"oct\", \"k\": \"r8hh3G0zJct-DF_NAaR5yw\", \"alg\": \"A128GCMKW\", \"kid\": \"A128GCMKW\"}" #if GNUTLS_VERSION_NUMBER >= 0x03060e ",{\"kty\": \"oct\", \"k\": \"y_x8eBUnma_IgqFEorIaJwCsCdnhQx1Z\", \"alg\": \"A192GCMKW\", \"kid\": \"A192GCMKW\"}" #endif ",{\"kty\": \"oct\", \"k\": \"LRt4ClEqexrcCTUgywVUlgVnlpXZpKUEhmr9kjVI6mI\", \"alg\": \"A256GCMKW\", \"kid\": \"A256GCMKW\"}" #if GNUTLS_VERSION_NUMBER >= 0x03060e ",{\"kty\": \"oct\", \"k\": \"4_24kl8FjgZAzoMPp57jLlMCWzegXVJVo1cooIo2cE0\", \"alg\": \"PBES2-HS256+A128KW\", \"kid\": \"PBES2-HS256+A128KW\"}" ",{\"kty\": \"oct\", \"k\": \"Vf0u-vnszx1mVBwscPLgHsaVOpeg47xJseZIIsoxJ80\", \"alg\": \"PBES2-HS384+A192KW\", \"kid\": \"PBES2-HS384+A192KW\"}" ",{\"kty\": \"oct\", \"k\": \"Ckym3KqZnG-VhBPBwffRQGshX4ZldrG9BVDBA4DAPw0\", \"alg\": \"PBES2-HS512+A256KW\", \"kid\": \"PBES2-HS512+A256KW\"}" #endif "]}"; const char jwks_all_pubkeys[] = "{\"keys\": [" "{\"kty\": \"RSA\", \"n\": \"AL9GIadpvuz-_1Xr2xAaZJwhxPqQ_xfanlYta3rg2cgBAryHUtWXlFP_FCGpYoX3kOlnDFpeczdc19Kt5K6YSaC9pTpBa_hT7iAzj8sx-YIx7JbAHXCnjM1LbsTA4_0T--Fv3xC4RtBktH4gjUwe3FDwyr87DyDt6d13wFBLvKKkggO70StGFRQucLY_ZXnSJIzJLdIpZ6H-0FFpaOw2kyS6zT1zxw71i1UtQodauFZvWuGIj6eDRakMJBaIkf59ZMXdgzcGuWea38JjpP6jU26q3PHXXUfdrL7QY0rzOROuoEDkeSyVdxAwFd3VdKhzWMJCLBDWg_yOuqr7fW3dzcU\", \"e\": \"AQAB\", \"kid\": \"RSA1_5\", \"alg\": \"RSA1_5\"}" #if NETTLE_VERSION_NUMBER >= 0x030400 ",{\"kty\": \"RSA\", \"n\": \"ALup-Z784fSG10vOGotny1I5G79Mw-MI8eXZmE1sR6d-1APlI3xDY6RBzjYHsmwyKL_Dxp6mkLkyzoom2c2flNwIDGyxXS9zMpBG84kE8jKiMP_N7tG0NkqZ45zJTDBg7VG1kxtcBZj5wuThPPy8SkbcQay9dH7-9u-6n-5suqMWG88YEbPugHbsiAhJ6hopKKX2-8VLJ7w0IMLXAlGXdaLz_6wh5S0KwwpMe0xEyiNCkWWFu9uNyuuR0UZPCZTQSTJssUUgCovnCKV_oS399G7M1k7qzOx0Y7EINvrcuxmpcLm9buAiDSlcn2DHRQNjAt3C3X7agLuquKl-NrG0-OU\", \"e\": \"AQAB\", \"kid\": \"RSA-OAEP\", \"alg\": \"RSA-OAEP\"}" ",{\"kty\": \"RSA\", \"n\": \"ANZKK6hNe1e9TwmRuT5Espfu7fslRrE1UmtSv1Xka1u9D75Wqt1flKqCThPaiqPpjbG8LX2zPk_f74vPFK6RvetgOVZOH3hJ3b5du051Dbcdiv_AVM3iWJSCqZyViVOb02Kh7EpXEAnvn2dfQW4ev23QoFx40rBwCW-quO139zoOEDc6WlJdn_DwmrpN0SadZmiMKyJvZlIo6p0BDbWAfj_PG7bGE_CwMmaxIg3rF_zUI2U4K1SQh45Fv2Dtgl_WZlJCEK0qOx2lmzN1wZLZk7M6bt9zW8OGYwHNY1gLSrdBkC_FN7ecbzApJ4QLkSJG1vKvpxLbqSXxPS1DXdGuNrs\", \"e\": \"AQAB\", \"kid\": \"RSA-OAEP-256\", \"alg\": \"RSA-OAEP-256\"}" ",{\"kty\": \"oct\", \"k\": \"wihT-v_265OXyGpOIe62hg\", \"alg\": \"A128KW\", \"kid\": \"A128KW\"}" ",{\"kty\": \"oct\", \"k\": \"OI_6XYApCCn_9R-8GPxOubBPkMNbt3Vd\", \"alg\": \"A192KW\", \"kid\": \"A192KW\"}" ",{\"kty\": \"oct\", \"k\": \"IZ2ifICT03pMCZfqHCtO1vPU1_yhGwZUu3Lt3NPiiow\", \"alg\": \"A256KW\", \"kid\": \"A256KW\"}" #endif #if NETTLE_VERSION_NUMBER >= 0x030600 ",{\"kty\": \"EC\", \"x\": \"AOJ9FiyptD67tbjYKAXr7sn7TzT5SAtcke5YcZjXbdLy\", \"y\": \"AMSB2nGzT4mCbai0hY_qODr4DaHVD9Gk_oJ9lXGb-TRw\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A128KW\", \"alg\": \"ECDH-ES+A128KW\"}" ",{\"kty\": \"EC\", \"x\": \"dQQcQ_TdYVScUzDaMdHUHvGZtfc_piecctF-q4Mz8PQ\", \"y\": \"AND5hLGPJKeEFDl_AQ9JsR5cE-uFUgvLQgPW9BgrluZJ\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A192KW\", \"alg\": \"ECDH-ES+A192KW\"}" ",{\"kty\": \"EC\", \"x\": \"AP4C-BLKoo98wrpMSuovvkhV2A7eyXwAw4DSa-Bs724I\", \"y\": \"djnAg_Fqjf9C23WsAI_c7ktV3XweOrfBA5lKzHjV4tw\", \"crv\": \"P-256\", \"kid\": \"ECDH-ES+A256KW\", \"alg\": \"ECDH-ES+A256KW\"}" ",{\"kty\": \"OKP\", \"x\": \"AuQ7nbIvxilE4nzzRoS_C_cmpqMx-kcXNkcAyy46fWM\", \"crv\": \"X25519\", \"kid\": \"ECDH-ES+A256KW-X25519\", \"alg\": \"ECDH-ES+A256KW\"}" ",{\"kty\":\"OKP\",\"crv\":\"X448\",\"x\":\"W46m2SwV-XgAWMqvPQe0KLy_-0CsHhb5r6y11aj7bJBK1F2fvWg02iEsGd5JyA5A3qllofTJwoQ\", \"kid\": \"ECDH-ES+A128KW-X448\", \"alg\": \"ECDH-ES+A128KW\"}" #endif ",{\"kty\": \"oct\", \"k\": \"r8hh3G0zJct-DF_NAaR5yw\", \"alg\": \"A128GCMKW\", \"kid\": \"A128GCMKW\"}" #if GNUTLS_VERSION_NUMBER >= 0x03060e ",{\"kty\": \"oct\", \"k\": \"y_x8eBUnma_IgqFEorIaJwCsCdnhQx1Z\", \"alg\": \"A192GCMKW\", \"kid\": \"A192GCMKW\"}" #endif ",{\"kty\": \"oct\", \"k\": \"LRt4ClEqexrcCTUgywVUlgVnlpXZpKUEhmr9kjVI6mI\", \"alg\": \"A256GCMKW\", \"kid\": \"A256GCMKW\"}" #if GNUTLS_VERSION_NUMBER >= 0x03060e ",{\"kty\": \"oct\", \"k\": \"4_24kl8FjgZAzoMPp57jLlMCWzegXVJVo1cooIo2cE0\", \"alg\": \"PBES2-HS256+A128KW\", \"kid\": \"PBES2-HS256+A128KW\"}" ",{\"kty\": \"oct\", \"k\": \"Vf0u-vnszx1mVBwscPLgHsaVOpeg47xJseZIIsoxJ80\", \"alg\": \"PBES2-HS384+A192KW\", \"kid\": \"PBES2-HS384+A192KW\"}" ",{\"kty\": \"oct\", \"k\": \"Ckym3KqZnG-VhBPBwffRQGshX4ZldrG9BVDBA4DAPw0\", \"alg\": \"PBES2-HS512+A256KW\", \"kid\": \"PBES2-HS512+A256KW\"}" #endif "]}"; #define JWE_FLATTENED "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_INVALID_JSON "error\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_PROTECTED "{\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_ENCRYPTED_KEY "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_IV "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_TAG "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_HEADER "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_ALG "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_MISSING_UNPROTECTED "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\"}" #define JWE_FLATTENED_MISSING_AAD "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_INVALID_ENC_KEY "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_INVALID_CIPHERTEXT "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7xAqonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpcCBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_FLATTENED_INVALID_AAD "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"encrypted_key\":\"63FSVQ9eI9WjN_8j9T0cd6irn_lX0_gO_2bLKmHc61Za8S3QW9VwYA\",\"iv\":\"deU9T1k-_6ohC0sGnnNLlA\",\"ciphertext\":\"ejhwuqZ9JMdTTWAv7x0qonqICYsgAFOgtB6CAt-xy5frcW0AGZ2UUlLqO6KXdNOHpL6ldakzEB-Luxpb8UAZvw\",\"tag\":\"Qojttvz7NaOc1Rvnv6w4Rg\",\"header\":{\"alg\":\"A128KW\",\"kid\":\"Ernie\"},\"aad\":\"RnJpZW5kc2hpACBpcyBtYWdpYwo\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_INVALID_JSON "error\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_MISSING_PROTECTED "{,\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_MISSING_IV "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_MISSING_CIPERTEXT "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_MISSING_TAG "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_MISSING_RECIPIENTS "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_EMPTY_RECIPIENTS "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_INVALID_CIPHERTEXT "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoaxAfnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_INVALID_TAG "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"KEeKAKbyG5_pHY0fon9a_A\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFpXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" #define JWE_GENERAL_INVALID_AAD "{\"protected\":\"eyJlbmMiOiJBMTI4Q0JDLUhTMjU2In0\",\"iv\":\"7faJWH0jrt1UcLMOPqCdcw\",\"ciphertext\":\"_9g8VmWcBlFEoax1fnLnNn2qgEsA15mBdIhwUS3biplvZjhJg1VRS6vCMib9E_Plrxi6G0PpnuvXfLeyuS2UOg\",\"tag\":\"YPFqTge_86Z3H-LU4AiccQ\",\"recipients\":[{\"encrypted_key\":\"3LuKb2XteFqe7oUlO5pmhsBLEOEH7RO5O1nLAWB6QpzycTW0ZD8A-g\",\"header\":{\"alg\":\"A128KW\"}},{\"encrypted_key\":\"VNBaXwpcZJEo1rgJ2_ZjGvIDbtJHggbILhgpJGyugF4gV584yhdQAXlOXV45VYcnPDrKOlVORS6S_xtw9JyuPoW8a09fHpkSqLzJKEBoKOpci99DZ4DUtpDMNqbR8YITpJhl5OY5fY8HLunlOlqR4JkItEZgBmN5Fzj_R_JBWTtZetd2ABeRKi_sofe2RxzQ7rx462g3YKHq7kU-murXw6CMqMtEx8SEwyyOAFOJ73SaAvalANSv2B_vcx5pXzariZRewZt79iJPKRPrdlm4vTc6bRJPKeniuBQJhEFMjNI-CzWambqrsihR_8JR82gBA0VFL-z2cWZhfXMpwX6vfw\",\"header\":{\"alg\":\"RSA1_5\"}},{\"encrypted_key\":\"1CpSZufVImvW5dl2gDBJS1VTjiBjE8RdEUQDhalEd58\",\"header\":{\"iv\":\"rGr-JToZe-Wpawrs\",\"tag\":\"_7pHIdTPXbG4ZZzdE6O_tw\",\"alg\":\"A128GCMKW\"}}],\"aad\":\"Um5KcFAXNWtjMmhwY0NCcGN5QnRZV2RwWXdv\",\"unprotected\":{\"jku\":\"https://equestria.tld/magic-keys.jwks\"}}" unsigned char aad[] = {70, 114, 105, 101, 110, 100, 115, 104, 105, 112, 32, 105, 115, 32, 109, 97, 103, 105, 99, 10}; void test_rhonabwy_json_flattened_all_algs(jwa_enc enc) { jwe_t * jwe, * jwe_decrypt; jwks_t * jwks_pub, * jwks_priv, * jwks_cur; jwk_t * jwk, * jwk_decrypt; json_t * j_result, * j_un_header = json_pack("{ss}", "jku", "https://equestria.tld/magic-keys.jwks"); size_t i; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pub), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_priv), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks_priv, jwks_all_privkeys), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks_pub, jwks_all_pubkeys), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_un_header), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_aad(jwe, aad, sizeof(aad)), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, enc), RHN_OK); for (i=0; ijwks_pubkey), json_array_size(json_object_get(j_result, "recipients"))); ck_assert_ptr_eq(NULL, json_object_get(j_result, "aad")); ck_assert_ptr_eq(NULL, json_object_get(j_result, "unprotected")); json_decref(j_result); ck_assert_int_eq(r_jwe_set_aad(jwe, aad, sizeof(aad)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jwe_serialize_json_t(jwe, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_ptr_ne(NULL, json_object_get(j_result, "protected")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "iv")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "ciphertext")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "tag")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "recipients")); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), json_array_size(json_object_get(j_result, "recipients"))); ck_assert_ptr_ne(NULL, json_object_get(j_result, "aad")); ck_assert_ptr_eq(NULL, json_object_get(j_result, "unprotected")); json_decref(j_result); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_un_header), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jwe_serialize_json_t(jwe, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_ptr_ne(NULL, json_object_get(j_result, "protected")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "iv")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "ciphertext")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "tag")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "recipients")); ck_assert_int_eq(r_jwks_size(jwe->jwks_pubkey), json_array_size(json_object_get(j_result, "recipients"))); ck_assert_ptr_ne(NULL, json_object_get(j_result, "aad")); ck_assert_ptr_ne(NULL, json_object_get(j_result, "unprotected")); json_decref(j_result); r_jwe_free(jwe); json_decref(j_un_header); } END_TEST START_TEST(test_rhonabwy_json_parse_general_error) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_INVALID_JSON, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_MISSING_PROTECTED, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_MISSING_IV, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_MISSING_CIPERTEXT, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_MISSING_TAG, 0), RHN_ERROR_PARAM); //ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_MISSING_RECIPIENTS, 0), RHN_ERROR_PARAM); //ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_EMPTY_RECIPIENTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_parse_general_ok) { jwe_t * jwe; size_t len = 0; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_get_enc(jwe), R_JWA_ENC_UNKNOWN); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_UNKNOWN); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwe_get_enc(jwe), R_JWA_ENC_A128CBC); ck_assert_int_eq(r_jwe_get_alg(jwe), R_JWA_ALG_UNKNOWN); ck_assert_ptr_ne(NULL, r_jwe_get_iv(jwe, &len)); ck_assert_int_eq(16, len); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_decrypt_general_invalid_key) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_privkey_rsa_str_2, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_decrypt_general_invalid_key_specified) { jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_ERROR_INVALID); r_jwk_free(jwk); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_decrypt_general_invalid_decryption) { jwe_t * jwe; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_key_symmetric_str, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_INVALID_CIPHERTEXT, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL_INVALID_AAD, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_ERROR_INVALID); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_decrypt_general_ok) { jwe_t * jwe; const unsigned char * payload; size_t payload_len; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_key_symmetric_str, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jwe_get_payload(jwe, &payload_len)); ck_assert_int_eq(o_strlen(PAYLOAD), payload_len); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, payload_len)); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_decrypt_general_without_kid_ok) { jwe_t * jwe; jwk_t * jwk; const unsigned char * payload; size_t payload_len; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwk_delete_property_str(jwk, "kid"), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, JWE_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jwe_get_payload(jwe, &payload_len)); ck_assert_int_eq(o_strlen(PAYLOAD), payload_len); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, payload_len)); r_jwk_free(jwk); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_flattened_flood) { jwe_t * jwe; json_t * j_un_header = json_pack("{ss}", "jku", "https://equestria.tld/magic-keys.jwks"); char * str_result; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_un_header), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_key_symmetric_str, jwk_key_symmetric_str), RHN_OK); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_FLATTENED)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_FLATTENED)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_FLATTENED)); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); json_decref(j_un_header); o_free(str_result); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_general_flood) { jwe_t * jwe; json_t * j_un_header = json_pack("{ss}", "jku", "https://equestria.tld/magic-keys.jwks"); char * str_result; ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_full_unprotected_header_json_t(jwe, j_un_header), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_key_symmetric_str, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys_json_str(jwe, jwk_key_aesgcm, jwk_key_aesgcm), RHN_OK); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_GENERAL)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_GENERAL)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jwe_serialize_json_str(jwe, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_parse_json_str(jwe, str_result, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); json_decref(j_un_header); o_free(str_result); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_json_flattened_all_algs_cbc) { test_rhonabwy_json_flattened_all_algs(R_JWA_ENC_A128CBC); } END_TEST START_TEST(test_rhonabwy_json_general_all_algs_cbc) { test_rhonabwy_json_general_all_algs(R_JWA_ENC_A128CBC); } END_TEST START_TEST(test_rhonabwy_json_flattened_all_algs_gcm) { test_rhonabwy_json_flattened_all_algs(R_JWA_ENC_A128GCM); } END_TEST START_TEST(test_rhonabwy_json_general_all_algs_gcm) { test_rhonabwy_json_general_all_algs(R_JWA_ENC_A128GCM); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE JSON function tests"); tc_core = tcase_create("test_rhonabwy_json"); tcase_add_test(tc_core, test_rhonabwy_json_flattened_error); tcase_add_test(tc_core, test_rhonabwy_json_flattened_ok); tcase_add_test(tc_core, test_rhonabwy_json_parse_flattened_error); tcase_add_test(tc_core, test_rhonabwy_json_parse_flattened_ok); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_flattened_invalid_key); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_flattened_invalid_key_specified); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_flattened_invalid_decryption); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_flattened_ok); tcase_add_test(tc_core, test_rhonabwy_json_general_error); tcase_add_test(tc_core, test_rhonabwy_json_general_ok); tcase_add_test(tc_core, test_rhonabwy_json_parse_general_error); tcase_add_test(tc_core, test_rhonabwy_json_parse_general_ok); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_general_invalid_key); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_general_invalid_key_specified); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_general_invalid_decryption); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_general_ok); tcase_add_test(tc_core, test_rhonabwy_json_decrypt_general_without_kid_ok); tcase_add_test(tc_core, test_rhonabwy_json_flattened_flood); tcase_add_test(tc_core, test_rhonabwy_json_general_flood); tcase_add_test(tc_core, test_rhonabwy_json_flattened_all_algs_cbc); tcase_add_test(tc_core, test_rhonabwy_json_general_all_algs_cbc); tcase_add_test(tc_core, test_rhonabwy_json_flattened_all_algs_gcm); tcase_add_test(tc_core, test_rhonabwy_json_general_all_algs_gcm); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE JSON tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_kw.c000066400000000000000000000730431452472117100160520ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define TOKEN "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_HEADER "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_ENCRYPTED_KEY "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-y8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_IV "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgQoD.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrg3E.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_TAG "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOB" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_7" #define TOKEN_INVALID_HEADER_B64 ";error;iOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.;error;nK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.;error;czZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.;error;Z3gDEpAMD_79pOw" #define TOKEN_INVALID_DOTS "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVALID_ENC "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Q.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVAlID_ENCRYPTED_KEY_LENGTH_SMALL "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" #define TOKEN_INVAlID_ENCRYPTED_KEY_LENGTH_LARGE "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.S7OUaa-1ekDy8cPPo1Rzq81vwaEfk3yBL5Xw9FnfRtGikBSwH0OC6Qee.29q9_PdnK2jXwG4gJvgDoQ.BuhbHPZczZ_XqNm8JwoW_B8rczVdVYO4o7pflVAcT0ojJg_m8Eo79F2W7FgLUEKVxrOoOz6-tuQjCzWfZkrE3g.p28K0cxZ3gDEpAMD_79pOw" const char jwk_key_invalid_small[] = "{\"kty\":\"oct\",\"k\":\"Z3J1dAo\"}"; const char jwk_key_invalid_large[] = "{\"kty\":\"oct\",\"k\":\"Z3J1dHBsb3Bjb2luZ25hYWdydXRwbG9wY29pbmduYWFncnV0cGxvcGNvaW5nbmFhZ3J1dHBsb3Bjb2luZ25hYQo\"}"; const char jwk_key_128_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODw\"}"; const char jwk_key_128_2[] = "{\"kty\":\"oct\",\"k\":\"CAkKCwwNDg8QERITFBUWFw\"}"; const char jwk_key_192_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYX\"}"; const char jwk_key_256_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8\"}"; #if NETTLE_VERSION_NUMBER >= 0x030400 START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENCRYPTED_KEY, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVAlID_ENCRYPTED_KEY_LENGTH_SMALL, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVAlID_ENCRYPTED_KEY_LENGTH_LARGE, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_invalid_privkey) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_enc, * jwk_dec; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_enc), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_dec), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_enc, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_dec, jwk_key_128_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_enc, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_dec, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_enc); r_jwk_free(jwk_dec); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_a128kw_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); // R_JWA_ENC_A128CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A192CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A256CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A128GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #if GNUTLS_VERSION_NUMBER >= 0x03060e // R_JWA_ENC_A192GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #endif // R_JWA_ENC_A256GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_a192kw_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_192_1), RHN_OK); // R_JWA_ENC_A128CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A192CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A256CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A128GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #if GNUTLS_VERSION_NUMBER >= 0x03060e // R_JWA_ENC_A192GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #endif // R_JWA_ENC_A256GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A192KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_a256kw_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_256_1), RHN_OK); // R_JWA_ENC_A128CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A192CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A256CBC ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); // R_JWA_ENC_A128GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #if GNUTLS_VERSION_NUMBER >= 0x03060e // R_JWA_ENC_A192GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A192GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); #endif // R_JWA_ENC_A256GCM ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_256_1), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_key_length) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_1, * jwk_2, * jwk_3, * jwk_4; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_2), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_3), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_4), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_1, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_2, jwk_key_256_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_3, jwk_key_invalid_small), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_4, jwk_key_invalid_large), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_1, 0)), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk_3, 0), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_1, jwk_4, 0), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_A256KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_2, 0)), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_2, jwk_3, 0), NULL); ck_assert_ptr_eq(r_jwe_serialize(jwe_enc_2, jwk_4, 0), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_1, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_3, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_4, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_2, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_3, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_4, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_2, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_1, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_1); r_jwk_free(jwk_2); r_jwk_free(jwk_3); r_jwk_free(jwk_4); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_rfc_example) { const char jwe_a_3[] = "eyJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.6KB707dM9YTIgHtLvtgWQ8mKwboJW3of9locizkDTHzBC2IlrT1oOQ.AxY8DCtDaGlsbGljb3RoZQ.KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.U0m_YmjN04DJvceFICbCVQ", jwe_a_3_key[] = "{\"kty\":\"oct\",\"k\":\"GawgguFyGrWKav7AX4VKUg\"}"; const unsigned char content[] = {76, 105, 118, 101, 32, 108, 111, 110, 103, 32, 97, 110, 100, 32, 112, 114, 111, 115, 112, 101, 114, 46}, cek[] = {4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}, iv[] = {3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}; char * token; jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwe_a_3_key), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, content, sizeof(content)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_A128KW), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_cypher_key(jwe, cek, sizeof(cek)), RHN_OK); ck_assert_int_eq(r_jwe_set_iv(jwe, iv, sizeof(iv)), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_str_eq(jwe_a_3, token); r_jwe_free(jwe); o_free(token); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, jwe_a_3, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); r_jwk_free(jwk); r_jwe_free(jwe); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE AES Key Wrap encryption tests"); tc_core = tcase_create("test_rhonabwy_kw"); #if NETTLE_VERSION_NUMBER >= 0x030400 tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_invalid_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_a128kw_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_a192kw_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_a256kw_ok); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_check_key_length); tcase_add_test(tc_core, test_rhonabwy_rfc_example); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE AES Key Wrap encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_pbes2.c000066400000000000000000000747031452472117100164500ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include void pbkdf2_hmac_sha384 (size_t key_length, const uint8_t *key, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst); void pbkdf2_hmac_sha512 (size_t key_length, const uint8_t *key, unsigned iterations, size_t salt_length, const uint8_t *salt, size_t length, uint8_t *dst); #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define TOKEN "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_HEADER "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQw.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_ENCRYPTED_KEY "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjav.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_IV "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pl.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgA0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_TAG "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2Aw" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cS" #define TOKEN_INVALID_HEADER_B64 ";error;ciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.;error;8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.;error;mfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R;error;" #define TOKEN_INVALID_DOTS "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_OVERSIZE_P2S "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiWlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlaWEp5YjNKbGNuSnZjbVZ5Y205eVpYSnliM0psY25KdmNtVnljbTl5WlhKeWIzSmxjbkp2Y21WeWNtOXlDZyIsInAyYyI6NDA5Nn0K.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_ENC "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTkyQ0JDLUhTMzg0IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_SMALL_P2S "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk8iLCJwMmMiOjQwOTZ9.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_P2S_B64 "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiO2Vycm9yOyIsInAyYyI6NDA5Nn0.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_P2S_TYPE "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjo0MiwicDJjIjo0MDk2fQ.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_P2C_NEG "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOi00Mn0.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" #define TOKEN_INVALID_P2C_STRING "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwicDJzIjoiTGZfbk9xdU9TM1UiLCJwMmMiOiIxMDAwIn0.vyYTdkjdPIv0DwxxaN1d0lILGkGXNiH8KzWb6nl8azjCJINwQ0Yjaw.jbfmnTw8AlsH9XwNIfc_pA.2hcZHvkmfnSQcnzVJ97T9kylIpZDBPtx43ODFye1l0Jf-IjB757r9cQHgmE5kdT9C_rmv4CGXf9ExVYVgX0AQA.p_gD5xAAVJOFs3R9cSb2ow" const char jwk_key_128_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODw\"}"; const char jwk_key_128_2[] = "{\"kty\":\"oct\",\"k\":\"CAkKCwwNDg8QERITFBUWFw\"}"; const char jwk_key_192_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYX\"}"; const char jwk_key_256_1[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8\"}"; const char password[] = "secret_password"; #if GNUTLS_VERSION_NUMBER >= 0x03060e START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_P2S_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_P2S_TYPE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_P2C_NEG, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_P2C_STRING, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENCRYPTED_KEY, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_OVERSIZE_P2S, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_decrypt); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_invalid_privkey) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_enc, * jwk_dec; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_enc), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_dec), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_enc, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_dec, jwk_key_128_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_enc, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_dec, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_enc); r_jwk_free(jwk_dec); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_pbes2_hs256_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_ptr_ne(jwk = r_jwk_quick_import(R_IMPORT_PASSWORD, password), NULL); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_pbes2_hs384_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H384), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_pbes2_hs512_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_128_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H512), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_256_1), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_flood_serialize_invalid_p2s_p2c) { jwe_t * jwe; jwk_t * jwk; ck_assert_ptr_ne(jwk = r_jwk_quick_import(R_IMPORT_PASSWORD, password), NULL); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "p2s", "cGxvcA"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "p2s", ";error;"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "p2s", ""), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "p2s", 42), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); r_jwe_free(jwe); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "p2c", "error"), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "p2c", -42), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk, 0), NULL); r_jwe_free(jwe); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_rfc_example) { const char jwe_a_c[] = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJwMnMiOiIyV0NUY0paMVJ2ZF9DSnVKcmlwUTF3IiwicDJjIjo0MDk2LCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiandrK2pzb24ifQ.TrqXOwuNUfDV9VPTNbyGvEJ9JMjefAVn-TR1uIxR9p6hsRQh9Tk7BA.Ye9j1qs22DmRSAddIh-VnA.AwhB8lxrlKjFn02LGWEqg27H4Tg9fyZAbFv3p5ZicHpj64QyHC44qqlZ3JEmnZTgQowIqZJ13jbyHB8LgePiqUJ1hf6M2HPLgzw8L-mEeQ0jvDUTrE07NtOerBk8bwBQyZ6g0kQ3DEOIglfYxV8-FJvNBYwbqN1Bck6d_i7OtjSHV-8DIrp-3JcRIe05YKy3Oi34Z_GOiAc1EK21B11c_AE11PII_wvvtRiUiG8YofQXakWd1_O98Kap-UgmyWPfreUJ3lJPnbD4Ve95owEfMGLOPflo2MnjaTDCwQokoJ_xplQ2vNPz8iguLcHBoKllyQFJL2mOWBwqhBo9Oj-O800as5mmLsvQMTflIrIEbbTMzHMBZ8EFW9fWwwFu0DWQJGkMNhmBZQ-3lvqTc-M6-gWA6D8PDhONfP2Oib2HGizwG1iEaX8GRyUpfLuljCLIe1DkGOewhKuKkZh04DKNM5Nbugf2atmU9OP0Ldx5peCUtRG1gMVl7Qup5ZXHTjgPDr5b2N731UooCGAUqHdgGhg0JVJ_ObCTdjsH4CF1SJsdUhrXvYx3HJh2Xd7CwJRzU_3Y1GxYU6-s3GFPbirfqqEipJDBTHpcoCmyrwYjYHFgnlqBZRotRrS95g8F95bRXqsaDY7UgQGwBQBwy665d0zpvTasvfXf_c0MWAl-neFaKOW_Px6g4EUDjG1GWSXV9cLStLw_0ovdApDIFLHYHePyagyHjouQUuGiq7BsYwYrwaF06tgB8hV8omLNfMEmDPJaZUzMuHw6tBDwGkzD-tS_ub9hxrpJ4UsOWnt5rGUyoN2N_c1-TQlXxm5oto14MxnoAyBQBpwIEgSH3Y4ZhwKBhHPjSo0cdwuNdYbGPpb-YUvF-2NZzODiQ1OvWQBRHSbPWYz_xbGkgD504LRtqRwCO7CC_CyyURi1sEssPVsMJRX_U4LFEOc82TiDdqjKOjRUfKK5rqLi8nBE9soQ0DSaOoFQZiGrBrqxDsNYiAYAmxxkos-i3nX4qtByVx85sCE5U_0MqG7COxZWMOPEFrDaepUV-cOyrvoUIng8i8ljKBKxETY2BgPegKBYCxsAUcAkKamSCC9AiBxA0UOHyhTqtlvMksO7AEhNC2-YzPyx1FkhMoS4LLe6E_pFsMlmjA6P1NSge9C5G5tETYXGAn6b1xZbHtmwrPScro9LWhVmAaA7_bxYObnFUxgWtK4vzzQBjZJ36UTk4OTB-JvKWgfVWCFsaw5WCHj6Oo4jpO7d2yN7WMfAj2hTEabz9wumQ0TMhBduZ-QON3pYObSy7TSC1vVme0NJrwF_cJRehKTFmdlXGVldPxZCplr7ZQqRQhF8JP-l4mEQVnCaWGn9ONHlemczGOS-A-wwtnmwjIB1V_vgJRf4FdpV-4hUk4-QLpu3-1lWFxrtZKcggq3tWTduRo5_QebQbUUT_VSCgsFcOmyWKoj56lbxthN19hq1XGWbLGfrrR6MWh23vk01zn8FVwi7uFwEnRYSafsnWLa1Z5TpBj9GvAdl2H9NHwzpB5NqHpZNkQ3NMDj13Fn8fzO0JB83Etbm_tnFQfcb13X3bJ15Cz-Ww1MGhvIpGGnMBT_ADp9xSIyAM9dQ1yeVXk-AIgWBUlN5uyWSGyCxp0cJwx7HxM38z0UIeBu-MytL-eqndM7LxytsVzCbjOTSVRmhYEMIzUAnS1gs7uMQAGRdgRIElTJESGMjb_4bZq9s6Ve1LKkSi0_QDsrABaLe55UY0zF4ZSfOV5PMyPtocwV_dcNPlxLgNAD1BFX_Z9kAdMZQW6fAmsfFle0zAoMe4l9pMESH0JB4sJGdCKtQXj1cXNydDYozF7l8H00BV_Er7zd6VtIw0MxwkFCTatsv_R-GsBCH218RgVPsfYhwVuT8R4HarpzsDBufC4r8_c8fc9Z278sQ081jFjOja6L2x0N_ImzFNXU6xwO-Ska-QeuvYZ3X_L31ZOX4Llp-7QSfgDoHnOxFv1Xws-D5mDHD3zxOup2b2TppdKTZb9eW2vxUVviM8OI9atBfPKMGAOv9omA-6vv5IxUH0-lWMiHLQ_g8vnswp-Jav0c4t6URVUzujNOoNd_CBGGVnHiJTCHl88LQxsqLHHIu4Fz-U2SGnlxGTj0-ihit2ELGRv4vO8E1BosTmf0cx3qgG0Pq0eOLBDIHsrdZ_CCAiTc0HVkMbyq1M6qEhM-q5P6y1QCIrwg.0HFmhOzsQ98nNWJjIHkR7A"; const unsigned char content[] = {123, 34, 107, 116, 121, 34, 58, 34, 82, 83, 65, 34, 44, 34, 107, 105, 100, 34, 58, 34, 106, 117, 108, 105, 101, 116, 64, 99, 97, 112, 117, 108, 101, 116, 46, 108, 105, 116, 34, 44, 34, 117, 115, 101, 34, 58, 34, 101, 110, 99, 34, 44, 34, 110, 34, 58, 34, 116, 54, 81, 56, 80, 87, 83, 105, 49, 100, 107, 74, 106, 57, 104, 84, 80, 56, 104, 78, 89, 70, 108, 118, 97, 100, 77, 55, 68, 102, 108, 87, 57, 109, 87, 101, 112, 79, 74, 104, 74, 54, 54, 119, 55, 110, 121, 111, 75, 49, 103, 80, 78, 113, 70, 77, 83, 81, 82, 121, 79, 49, 50, 53, 71, 112, 45, 84, 69, 107, 111, 100, 104, 87, 114, 48, 105, 117, 106, 106, 72, 86, 120, 55, 66, 99, 86, 48, 108, 108, 83, 52, 119, 53, 65, 67, 71, 103, 80, 114, 99, 65, 100, 54, 90, 99, 83, 82, 48, 45, 73, 113, 111, 109, 45, 81, 70, 99, 78, 80, 56, 83, 106, 103, 48, 56, 54, 77, 119, 111, 113, 81, 85, 95, 76, 89, 121, 119, 108, 65, 71, 90, 50, 49, 87, 83, 100, 83, 95, 80, 69, 82, 121, 71, 70, 105, 78, 110, 106, 51, 81, 81, 108, 79, 56, 89, 110, 115, 53, 106, 67, 116, 76, 67, 82, 119, 76, 72, 76, 48, 80, 98, 49, 102, 69, 118, 52, 53, 65, 117, 82, 73, 117, 85, 102, 86, 99, 80, 121, 83, 66, 87, 89, 110, 68, 121, 71, 120, 118, 106, 89, 71, 68, 83, 77, 45, 65, 113, 87, 83, 57, 122, 73, 81, 50, 90, 105, 108, 103, 84, 45, 71, 113, 85, 109, 105, 112, 103, 48, 88, 79, 67, 48, 67, 99, 50, 48, 114, 103, 76, 101, 50, 121, 109, 76, 72, 106, 112, 72, 99, 105, 67, 75, 86, 65, 98, 89, 53, 45, 76, 51, 50, 45, 108, 83, 101, 90, 79, 45, 79, 115, 54, 85, 49, 53, 95, 97, 88, 114, 107, 57, 71, 119, 56, 99, 80, 85, 97, 88, 49, 95, 73, 56, 115, 76, 71, 117, 83, 105, 86, 100, 116, 51, 67, 95, 70, 110, 50, 80, 90, 51, 90, 56, 105, 55, 52, 52, 70, 80, 70, 71, 71, 99, 71, 49, 113, 115, 50, 87, 122, 45, 81, 34, 44, 34, 101, 34, 58, 34, 65, 81, 65, 66, 34, 44, 34, 100, 34, 58, 34, 71, 82, 116, 98, 73, 81, 109, 104, 79, 90, 116, 121, 115, 122, 102, 103, 75, 100, 103, 52, 117, 95, 78, 45, 82, 95, 109, 90, 71, 85, 95, 57, 107, 55, 74, 81, 95, 106, 110, 49, 68, 110, 102, 84, 117, 77, 100, 83, 78, 112, 114, 84, 101, 97, 83, 84, 121, 87, 102, 83, 78, 107, 117, 97, 65, 119, 110, 79, 69, 98, 73, 81, 86, 121, 49, 73, 81, 98, 87, 86, 86, 50, 53, 78, 89, 51, 121, 98, 99, 95, 73, 104, 85, 74, 116, 102, 114, 105, 55, 98, 65, 88, 89, 69, 82, 101, 87, 97, 67, 108, 51, 104, 100, 108, 80, 75, 88, 121, 57, 85, 118, 113, 80, 89, 71, 82, 48, 107, 73, 88, 84, 81, 82, 113, 110, 115, 45, 100, 86, 74, 55, 106, 97, 104, 108, 73, 55, 76, 121, 99, 107, 114, 112, 84, 109, 114, 77, 56, 100, 87, 66, 111, 52, 95, 80, 77, 97, 101, 110, 78, 110, 80, 105, 81, 103, 79, 48, 120, 110, 117, 84, 111, 120, 117, 116, 82, 90, 74, 102, 74, 118, 71, 52, 79, 120, 52, 107, 97, 51, 71, 79, 82, 81, 100, 57, 67, 115, 67, 90, 50, 118, 115, 85, 68, 109, 115, 88, 79, 102, 85, 69, 78, 79, 121, 77, 113, 65, 68, 67, 54, 112, 49, 77, 51, 104, 51, 51, 116, 115, 117, 114, 89, 49, 53, 107, 57, 113, 77, 83, 112, 71, 57, 79, 88, 95, 73, 74, 65, 88, 109, 120, 122, 65, 104, 95, 116, 87, 105, 90, 79, 119, 107, 50, 75, 52, 121, 120, 72, 57, 116, 83, 51, 76, 113, 49, 121, 88, 56, 67, 49, 69, 87, 109, 101, 82, 68, 107, 75, 50, 97, 104, 101, 99, 71, 56, 53, 45, 111, 76, 75, 81, 116, 53, 86, 69, 112, 87, 72, 75, 109, 106, 79, 105, 95, 103, 74, 83, 100, 83, 103, 113, 99, 78, 57, 54, 88, 53, 50, 101, 115, 65, 81, 34, 44, 34, 112, 34, 58, 34, 50, 114, 110, 83, 79, 86, 52, 104, 75, 83, 78, 56, 115, 83, 52, 67, 103, 99, 81, 72, 70, 98, 115, 48, 56, 88, 98, 111, 70, 68, 113, 75, 117, 109, 51, 115, 99, 52, 104, 51, 71, 82, 120, 114, 84, 109, 81, 100, 108, 49, 90, 75, 57, 117, 119, 45, 80, 73, 72, 102, 81, 80, 48, 70, 107, 120, 88, 86, 114, 120, 45, 87, 69, 45, 90, 69, 98, 114, 113, 105, 118, 72, 95, 50, 105, 67, 76, 85, 83, 55, 119, 65, 108, 54, 88, 118, 65, 82, 116, 49, 75, 107, 73, 97, 85, 120, 80, 80, 83, 89, 66, 57, 121, 107, 51, 49, 115, 48, 81, 56, 85, 75, 57, 54, 69, 51, 95, 79, 114, 65, 68, 65, 89, 116, 65, 74, 115, 45, 77, 51, 74, 120, 67, 76, 102, 78, 103, 113, 104, 53, 54, 72, 68, 110, 69, 84, 84, 81, 104, 72, 51, 114, 67, 84, 53, 84, 51, 121, 74, 119, 115, 34, 44, 34, 113, 34, 58, 34, 49, 117, 95, 82, 105, 70, 68, 80, 55, 76, 66, 89, 104, 51, 78, 52, 71, 88, 76, 84, 57, 79, 112, 83, 75, 89, 80, 48, 117, 81, 90, 121, 105, 97, 90, 119, 66, 116, 79, 67, 66, 78, 74, 103, 81, 120, 97, 106, 49, 48, 82, 87, 106, 115, 90, 117, 48, 99, 54, 73, 101, 100, 105, 115, 52, 83, 55, 66, 95, 99, 111, 83, 75, 66, 48, 75, 106, 57, 80, 97, 80, 97, 66, 122, 103, 45, 73, 121, 83, 82, 118, 118, 99, 81, 117, 80, 97, 109, 81, 117, 54, 54, 114, 105, 77, 104, 106, 86, 116, 71, 54, 84, 108, 86, 56, 67, 76, 67, 89, 75, 114, 89, 108, 53, 50, 122, 105, 113, 75, 48, 69, 95, 121, 109, 50, 81, 110, 107, 119, 115, 85, 88, 55, 101, 89, 84, 66, 55, 76, 98, 65, 72, 82, 75, 57, 71, 113, 111, 99, 68, 69, 53, 66, 48, 102, 56, 48, 56, 73, 52, 115, 34, 44, 34, 100, 112, 34, 58, 34, 75, 107, 77, 84, 87, 113, 66, 85, 101, 102, 86, 119, 90, 50, 95, 68, 98, 106, 49, 112, 80, 81, 113, 121, 72, 83, 72, 106, 106, 57, 48, 76, 53, 120, 95, 77, 79, 122, 113, 89, 65, 74, 77, 99, 76, 77, 90, 116, 98, 85, 116, 119, 75, 113, 118, 86, 68, 113, 51, 116, 98, 69, 111, 51, 90, 73, 99, 111, 104, 98, 68, 116, 116, 54, 83, 98, 102, 109, 87, 122, 103, 103, 97, 98, 112, 81, 120, 78, 120, 117, 66, 112, 111, 79, 79, 102, 95, 97, 95, 72, 103, 77, 88, 75, 95, 108, 104, 113, 105, 103, 73, 52, 121, 95, 107, 113, 83, 49, 119, 89, 53, 50, 73, 119, 106, 85, 110, 53, 114, 103, 82, 114, 74, 45, 121, 89, 111, 49, 104, 52, 49, 75, 82, 45, 118, 122, 50, 112, 89, 104, 69, 65, 101, 89, 114, 104, 116, 116, 87, 116, 120, 86, 113, 76, 67, 82, 86, 105, 68, 54, 99, 34, 44, 34, 100, 113, 34, 58, 34, 65, 118, 102, 83, 48, 45, 103, 82, 120, 118, 110, 48, 98, 119, 74, 111, 77, 83, 110, 70, 120, 89, 99, 75, 49, 87, 110, 117, 69, 106, 81, 70, 108, 117, 77, 71, 102, 119, 71, 105, 116, 81, 66, 87, 116, 102, 90, 49, 69, 114, 55, 116, 49, 120, 68, 107, 98, 78, 57, 71, 81, 84, 66, 57, 121, 113, 112, 68, 111, 89, 97, 78, 48, 54, 72, 55, 67, 70, 116, 114, 107, 120, 104, 74, 73, 66, 81, 97, 106, 54, 110, 107, 70, 53, 75, 75, 83, 51, 84, 81, 116, 81, 53, 113, 67, 122, 107, 79, 107, 109, 120, 73, 101, 51, 75, 82, 98, 66, 121, 109, 88, 120, 107, 98, 53, 113, 119, 85, 112, 88, 53, 69, 76, 68, 53, 120, 70, 99, 54, 70, 101, 105, 97, 102, 87, 89, 89, 54, 51, 84, 109, 109, 69, 65, 117, 95, 108, 82, 70, 67, 79, 74, 51, 120, 68, 101, 97, 45, 111, 116, 115, 34, 44, 34, 113, 105, 34, 58, 34, 108, 83, 81, 105, 45, 119, 57, 67, 112, 121, 85, 82, 101, 77, 69, 114, 80, 49, 82, 115, 66, 76, 107, 55, 119, 78, 116, 79, 118, 115, 53, 69, 81, 112, 80, 113, 109, 117, 77, 118, 113, 87, 53, 55, 78, 66, 85, 99, 122, 83, 99, 69, 111, 80, 119, 109, 85, 113, 113, 97, 98, 117, 57, 86, 48, 45, 80, 121, 52, 100, 81, 53, 55, 95, 98, 97, 112, 111, 75, 82, 117, 49, 82, 57, 48, 98, 118, 117, 70, 110, 85, 54, 51, 83, 72, 87, 69, 70, 103, 108, 90, 81, 118, 74, 68, 77, 101, 65, 118, 109, 106, 52, 115, 109, 45, 70, 112, 48, 111, 89, 117, 95, 110, 101, 111, 116, 103, 81, 48, 104, 122, 98, 73, 53, 103, 114, 121, 55, 97, 106, 100, 89, 121, 57, 45, 50, 108, 78, 120, 95, 55, 54, 97, 66, 90, 111, 79, 85, 117, 57, 72, 67, 74, 45, 85, 115, 102, 83, 79, 73, 56, 34, 125}, cek[] = {111, 27, 25, 52, 66, 29, 20, 78, 92, 176, 56, 240, 65, 208, 82, 112, 161, 131, 36, 55, 202, 236, 185, 172, 129, 23, 153, 194, 195, 48, 253, 182}, iv[] = {97, 239, 99, 214, 171, 54, 216, 57, 145, 72, 7, 93, 34, 31, 149, 156}; const char passphrase_a_c[] = "Thus from my lips, by yours, my sin is purged."; char * token; jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_password(jwk, passphrase_a_c), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, content, sizeof(content)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_PBES2_H256), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "p2s", "2WCTcJZ1Rvd_CJuJripQ1w"), RHN_OK); ck_assert_int_eq(r_jwe_set_header_int_value(jwe, "p2c", 4096), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwe_set_header_str_value(jwe, "cty", "jwk+json"), RHN_OK); ck_assert_int_eq(r_jwe_set_cypher_key(jwe, cek, sizeof(cek)), RHN_OK); ck_assert_int_eq(r_jwe_set_iv(jwe, iv, sizeof(iv)), RHN_OK); ck_assert_int_eq(r_jwe_set_full_header_json_str(jwe, "{\"alg\":\"PBES2-HS256+A128KW\",\"p2s\":\"2WCTcJZ1Rvd_CJuJripQ1w\",\"p2c\":4096,\"enc\":\"A128CBC-HS256\",\"cty\":\"jwk+json\"}"), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk, 0)), NULL); ck_assert_str_eq(jwe_a_c, token); r_jwe_free(jwe); o_free(token); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, jwe_a_c, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); r_jwk_free(jwk); r_jwe_free(jwe); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE PBES2 encryption tests"); tc_core = tcase_create("test_rhonabwy_pbes"); #if GNUTLS_VERSION_NUMBER >= 0x03060e tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_invalid_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_pbes2_hs256_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_pbes2_hs384_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_pbes2_hs512_ok); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_flood_serialize_invalid_p2s_p2c); tcase_add_test(tc_core, test_rhonabwy_rfc_example); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE PBES2 encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_rsa.c000066400000000000000000000736031452472117100162200ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define TOKEN "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_HEADER "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_ENCRYPTED_KEY "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RT6guFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_IV "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H6x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PP6NjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_TAG "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B6yKQIkFi4TTg" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg2In0" #define TOKEN_INVALID_HEADER_B64 ";error;.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.;error;.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.;error;.UZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.;error;" #define TOKEN_INVALID_DOTS "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5MUZtem8uW9B2yKQIkFi4TTg" #define TOKEN_INVALID_ENC "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIn0.q3rOIk7Tl3z9RTtguFTV7LLs7K7xegFelcRu245n73tXloZS5FojCE_Ib4HdX_Hw5qG7-Rq_6_3zSJ72NuLzvHm2HsJmCbGxEIf3hOgDUqeNKZ_zpc1ivMjqlynplqXxk9llkmizUGSz_4o9zI6_4ZkRuJK_jeAhqcnDMT1z53a2p7xcbkpDzrQQnIHUcPoe7v19r8kwk7wgaF0i64_l0oyvqCwIMDm07nsCPB_Ry55U-k1YftsfricboBk8jWLia7ObNKxtjxw3ntZjJAXxPdCaeYMoBi7D5iZfW-1OIsVJWEujhSbpwdAJEpBvOnHwDZXQ42rzg4R14mE46aq3Ew.m08H3x7QMOgukOdgsFod9Q.BlnT2QPAZnruTe4xi78e2ufYrZQqb8k0b7wy4tEuGmANid7fb56oDuCxNz0oWQd-yEfp0j1eUUuKn0gG9Mef-1W4Fk3sg8ekPD1PPWNjK5M.UZtem8uW9B2yKQIkFi4TTg" const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":\"2\"}"; START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENCRYPTED_KEY, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_invalid_privkey) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_2_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_pubkey, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_key_length) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_rsa2048_pub, * jwk_rsa2048_priv, * jwk_rsa4096_pub, * jwk_rsa4096_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_pub, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_pub, jwk_pubkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_priv, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_rsa2048_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_rsa4096_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa2048_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa4096_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa4096_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa2048_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_rsa2048_pub); r_jwk_free(jwk_rsa2048_priv); r_jwk_free(jwk_rsa4096_pub); r_jwk_free(jwk_rsa4096_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST /** * Test decrypting the JWE in the RFC 7516 * A.2. Example JWE using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 * https://tools.ietf.org/html/rfc7516#page-36 */ START_TEST(test_rhonabwy_decrypt_rfc_ok) { const char token[] = "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0."\ "UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm"\ "1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7Pc"\ "HALUzoOegEI-8E66jX2E4zyJKx-YxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIF"\ "NPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8"\ "rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTP-cFPgwCp6X-nZZd9OHBv"\ "-B3oWh2TbqmScqXMR4gp_A."\ "AxY8DCtDaGlsbGljb3RoZQ."\ "KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY."\ "9hH0vgRfYgPnAHOd8stkvw", privkey[] = "{\"kty\":\"RSA\","\ "\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl"\ "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre"\ "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_"\ "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI"\ "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU"\ "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\","\ "\"e\":\"AQAB\","\ "\"d\":\"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq"\ "1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry"\ "nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_"\ "0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj"\ "-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj"\ "T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ\","\ "\"p\":\"9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68"\ "ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP"\ "krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM\","\ "\"q\":\"uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y"\ "BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN"\ "-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0\","\ "\"dp\":\"w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv"\ "ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra"\ "Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs\","\ "\"dq\":\"o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff"\ "7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_"\ "odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU\","\ "\"qi\":\"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC"\ "tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ"\ "B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo\""\ "}", plaintext[] = "Live long and prosper."; jwe_t * jwe; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, privkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe->payload, plaintext, jwe->payload_len)); r_jwk_free(jwk_privkey); r_jwe_free(jwe); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE RSA key encryption tests"); tc_core = tcase_create("test_rhonabwy_rsa"); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_invalid_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_2_ok); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_check_key_length); tcase_add_test(tc_core, test_rhonabwy_decrypt_rfc_ok); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE RSA key encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwe_rsa_oaep.c000066400000000000000000001501021452472117100172120ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define TOKEN "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_HEADER "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_ENCRYPTED_KEY "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYA6-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_IV "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcEgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_CIPHER "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTY666JtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_TAG "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iweEOgQ" #define TOKEN_INVALID_TAG_LEN "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwe" #define TOKEN_INVALID_HEADER_B64 ";error;iOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_IV_B64 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.;error;JEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_CIPHER_B64 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.;error;ImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_TAG_B64 "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.;error;8vjDLxu9iwepOgQ" #define TOKEN_INVALID_DOTS "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" #define TOKEN_INVALID_ENC "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExOTJDQkMtSFMzODQiLCJraWQiOiIyMDExLTA0LTI5In0.hTdKQoNUPNyaiJrY2w08F7AMfgQqPlJU_OhiBMpbc4qpEyqN9H_rmT1qWbyihrZdYAA-erClptOnX2jJZJit83iIykfPyHsWpOENGfN6S8U8oopVgOJWRW2C1TP9hpn1zVmAnvAXlVjAie2frs_zE7S2Rx2IFpFCbu5G1bcc0ERbAhLLxInqUlRl2wblefWUrd22kalO5ozQny1BnKkRnLJ80eD98RFrvV2ie1DO5bZBFRQzypKmXzjpLTsfT0BvX2-ReYodMC07-5feH_d5nFNcqerf2FLUcuItQLShZENzmW9gqlvaiggppPbax9A5UlCMQ2TQX64IXX5GvNSViA.jcPgqVtJEEf237zYfmGFvg.4FyxKUqImoKN_9VnKu9BVCA_vRL6A3gjFb_TSqlD43oLsBw9vJaWVpc5v6ZFHRrpdyxScMQTYKUQJtmLZeFiPw.hpofnoY8vjDLxu9iwepOgQ" const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_3015_str[] = "{\"kty\":\"RSA\",\"n\":\"UkE5utIP_jhZm_HxNa4ITmjhIYSYCctVQF9R8gmwj2WMdq0sV8IonqnjmJkrx1w0X5qUI7LMD6seMbZYyN41VRhbHm7Nq8sJ1Eyi"\ "7JhF0nQsiTpYeopAHbDIJvGh7lAtOSSLzyz-jIaRFGgIymFCLrlVM3Jehn87N19IDNX2VizHw8JnAL5ZAEbAoFCm1NhkAQT3P-cUTCg5YBxCy_zF1Cjqn0tzk4bVE"\ "Y7001VCeSk8dwmj_5HU62T_TECyQwlKTDdaJaC7ni6gxA-p0UC9oloHCuvVm4Li0PcJILVCtSSUoO7kNDWb2RKpl6fURKNz9a_in02jOOeH46v2vaBU_XfRDwbEcZ"\ "3FFbLAw42VRv5C0YCuuGhNERZpWhPqC3fzf6VC7RJ6ZW5XtcfvCrOc3qjPGZsDxMFxAKFgJBSlQ57IIattYbsmkIA3rk_aQBZrxNGVFvrpwaQ3I7OZXA6MQWuNwBM"\ "onk1rmrKoXcpxzf-y7NNXTfauDP8\",\"e\":\"AQAB\",\"d\":\"HRaD29U9YqF6zvMYYetRdKkSNFA3k_8b_s-2oulaTtuSeMV00PQQeUuK-QPxv2aT_tsjWBx"\ "6nW_eFaZub1plcdpTHsgAY6hBqZoQY6rVxj7fIQhJEcyiL928akk5ApXH6FVMO8-llPxhgd3ofek3Bl70CmV_mACWaFaBnEht_LuJSWkOE-08fCSJKihbVxnPA61F"\ "4otNWkE_SQW1eX3CV-zAS-Ta0mj0IGl1muajw0UZ5N676D0iFrx4q_aORDSZR5r9ce0DAIGoYrrPi3w22yZIFOTIKrTs-4AqaQSum6n6m_NAVibMIYQl81jVxxQ9M"\ "hFOoIGAUFNBiD-5u_xbeB0ne6nwWR8L7TFT4nl5yORMvu8nbzi41MofrXMyBQJO9ccGKMfu6RhQVPQGFI-ctFpIKysvGAlMarQvAR3RA65w01ShqWyWBGGCPTq-of"\ "2WtxnZQmNJnlctZlU9drq7TTIrs99KHjYEl5-wYE2PLd_2-WnNlOl2JgE\",\"p\":\"DN1pM-wKkTMpacxQOY8RHuS9ls1GqBNoFvzRo6-FW_Aj49Y1uPov8DeG2"\ "b1NyPqXMv8xbyjONpMtc1TTby_6Kp4dr_r79XoEgGC0WnXJSLk_cUb5YHB5N_yDeKvlqa9vRBZPiX0PVAI97_4R9x-89fd4TRJ-ot-M1308HMhKoGvmqus5ZkLgni"\ "EH89np_cZnJcHaXNZpQkua2xT0FH3WVkiElQ2PpkbcxpWoSacu6IhRVQTqN1bSkghRHy2h\",\"q\":\"BmTMYx7TCVAFGDtT6_l84fwF_21z1RQuJjEmKPIcVjkm"\ "RgkqhmZZjGe0ehXvCNODOtrDiNb40Q2gZiDV9CrjWXhAjUcjaBO2OcgalNFAUnExo6olsdRkzDP7t1mU6GiZ35IjgpND4oxMXr0sjgl9o-Hyv4nP5ls-kr_2CVQq_"\ "PzgR4_O7nFr77R7AK_Jq9NDrkFNjBiNbwZxVUMUkU-tUzQk8HzKOIckM5SHaQZKIkZt5UC-H1C26BpbePaf\",\"qi\":\"C-WQU2YoqY_ux_FLXvldlbbiHiisP9"\ "xLdL0NsiCEgN2karv6uWXdNih9e7rAr0zTFotOLgysRkU7jzK1dCRfq7hroHmA0q_ljsxuyB_GlAhFi219aoKchS4nDsHr70x2eLDJnLkVKTQg2TaGjGUbgV892tu"\ "J05vwmKBIYWngRnzB1nRWKk9sz4AskXALW8JWNMm1-Hp3ZrkqxnwZ7c_hDkKPErIy26mfcIfKccsASTxmVLijA9NNuUPUUifN\",\"dp\":\"iPBH5WenE-6D5Kft"\ "TMKUe0Ra0dw_PtdUJVz-Jl0wLnL_lTeUomp93YEw6osicTD6QNwoWBUC9ems4vkLpX4MaZioaZIyacloIR0-qakd6f32UtIprWOM7WX2DYe2H4JL3XWfLOEHSDSVF"\ "wZeNSahP5Hz-nHjidIMX7uxIq7frrzfnHo9g0hdqtfuzr_I-oftbPsMYynrRMOCmoNvmq_f1JIWtIKlkkq5wx1FOrtblddz5olqlaSZx9i_qCE\",\"dq\":\"BSg"\ "Jxe64GAyW70H5npfo5YARfjxRbIkH5vlAY0lPHSKeAWGnEBk_IwMIBGXoD2A1t6NyisuEg2TP9U2J_48PJ7rZpJa4sVkkX1lIRrizfUmY1PuFxvMaD63k1avDcePa"\ "JPqA9O-7kdvAQ6-hXTO-RgsVcO-94XO49TUnQcLFoJ54an5KTvbeK8WMZbNfm9mX_dLgrZmnhuDVSgP9dGujxzSIjgK2O_yRb5_bzRGrfBT80CT0r-CygmGvX9DV\""\ ",\"kid\":\"3015\"}"; const char jwk_pubkey_rsa_3015_str[] = "{\"kty\":\"RSA\",\"n\":\"UkE5utIP_jhZm_HxNa4ITmjhIYSYCctVQF9R8gmwj2WMdq0sV8IonqnjmJkrx1w0X5qUI7LMD6seMbZYyN41VRhbHm7Nq8sJ1Eyi7"\ "JhF0nQsiTpYeopAHbDIJvGh7lAtOSSLzyz-jIaRFGgIymFCLrlVM3Jehn87N19IDNX2VizHw8JnAL5ZAEbAoFCm1NhkAQT3P-cUTCg5YBxCy_zF1Cjqn0tzk4bVEY7"\ "001VCeSk8dwmj_5HU62T_TECyQwlKTDdaJaC7ni6gxA-p0UC9oloHCuvVm4Li0PcJILVCtSSUoO7kNDWb2RKpl6fURKNz9a_in02jOOeH46v2vaBU_XfRDwbEcZ3FF"\ "bLAw42VRv5C0YCuuGhNERZpWhPqC3fzf6VC7RJ6ZW5XtcfvCrOc3qjPGZsDxMFxAKFgJBSlQ57IIattYbsmkIA3rk_aQBZrxNGVFvrpwaQ3I7OZXA6MQWuNwBMonk1"\ "rmrKoXcpxzf-y7NNXTfauDP8\",\"e\":\"AQAB\",\"kid\":\"3015\"}"; const char jwk_privkey_rsa_4109_str[] = "{\"kty\":\"RSA\",\"n\":\"GBCMlNgIVKgDhxhYog5r-Qt7KD2GsLRQmQvTImLeqf8VOZzK5cF4vF-N9apBW8MksV29g1vUljCFz1EXrz6EaO30LbC8wa0g-gXa"\ "m9pT0QPXOBr2knOHWSCpxVk6ZlVpClOecuy5dvTorZTxNbTtkh4YWlSo5nieAKkZgFR4kQl1DXxpdfGdcXaVfc-QL5npPvwv3Q15aVmiilcAY_-tMw-MACPm6zG6W"\ "7PeilGaH-Y24_E6PMZNA3bxdFQ1do56V1i7DdlH_CZpa2sbv4e5q3mlcg6G0nNN3HqGqIBwkT_Y8Q5vNs2bhzXRDWQjRdouRMs1VZkKJrMX-yZHgKI1xr_LlwnmxL"\ "Gq1zWTf6_beiZxmeGRu7tkXKgEaQ8yffokv2o0nI5dKn7U8SWKlRNP-ansyuouaxCWOrIrfjo0ABA6pV_PsBJJ_wOqX0WucYGJANM89LDMC_FPjjqg7Fze8cjMyMF"\ "SHBJgbWTGD_951iBZhnf69PgfC-AoKNnM4xkib1Xp3_i0o7Al3vJSmBuY5qSn0iLoUcn5SbpEuqZOCwZ6grSzwbyWljSSr_w7vg8mB-RZLvEehR4GQ6lCY17gDB4Z"\ "e4trE4YIvYxDJNde1XIwcaZCVWrtoyC_sbr_OtrDcxetCbnDkmawBX-8idEwZgE8O99s-D2wGH7c2A4iDUFh2w\",\"e\":\"AQAB\",\"d\":\"B25k2znzKKFRp"\ "ZBBHpoxgZCoEX8ebsbf9MMQChhaBkj9NvNSPK0IKbOgVPKkiD-0vwjhkwTymwaU67ZxB-7YWMbSlqFzSKO8ATl5jpNXOr5i4bKB3ivK6h0KECVDwYIyk7vKvFaZ10"\ "A98gyCiEE889hTUOG_3pv0vuN5OoXbTX6MJQP8VS2tnvItq9JDBlATFR4vcaXNjljdtrazKi40QAZXB1wO3SZYFCVxXWlhnOQsoytE_quF8MH0QiYW9Gt_ICYIbXh"\ "hoF4EQ-WphfXVwjwoeRY_UBHHQ4SavMIdAN2kkpwQf-3yT0ixK992fQWpMBlIeQxvdA_uIeJqRjDRRnSUw85b0JJGYg5QvE3w9tF0he4cR7RJV5I3St1ivqxMdPnp"\ "xcCVkGrM8nXT8HMZbL3G6c4BfNhwFrtWeowu0YX3cJX6fYAcoHWt4uuBxxZJi60LrJC8W1uaoDF0t3xIH0NK_Lym7SKpdd7vNGzOwV5f39wErXGwGFz_jXd-x-H6T"\ "qgt_eXz-y2xX5cWavEXsH7cf8v4Mt7WTps_CO1sEl5IBPAgR-Y-Oiu_f3XT87kznaHEfc8glzJqOKTpNJdVVLw8oBhwu_kxpQ7V9GBobT1TCiKRVhTBtvKWpANxcJ"\ "XP6t6bbb3N-EckCubSS7LhZG4TeNWbxHgVncyTGqkc4f9w8Q\",\"p\":\"bOB6_y6_syB3efXtxMa0Ln1MqHcNMw7UaMjWVGlrHvSdjADvAmARZm6IZ7lnjiDHGD"\ "ucyIgo71HRh_NRUuYaLT8EX27kEpQRXpat89Fo7DoZ8xPbytuCgCWBX0VYiNL_eZVlg6hAjF56SXRaAdAMwa29SkzIVpKGfW5-Gca45d9yCdRjRV5bNWlr0v7Xaem"\ "lu2sa3ZOzlvik7f03baBSKxlLSp_V2N0dQCEb7pf73JGOQzcfbMwG1-ysYIuC776IpFhh713n9LYVnzna6MRPotv4j6oIDHO6S63u0P-uOhAW30Tq06y8hxIiVOuv"\ "7p9BuCH1551G50Yhf4sqlDEs8Ec\",\"q\":\"OJUsuWdEew_PsqO00OQ-IR4d7XhiYjvlLgRlujsgWcs5j6RfFCS2-9bmbBHZHqvJw3AL6HGEFr3TcVnYvyDvCEh"\ "PNJs2PBDG9F4-XUPHi-15ar8adsCPuW1GxGkl_SzIvW41YbHokIdVfNgCbXJRANWReKbkTACpFNNqjAgnCIOdLoWGfAhQmy93fv28ETd0Zi7plQQTlhXdOvWkPqh0"\ "X_eXCNgl9ijjL4D4ZLUtRv9p6yrnCp6QhaiJi9VFloqiuOi1P9jPKbuCixWVwzuw4aJ1neqH_upHl_t5IY5XT5HtERwzWi1MGC1J29wY8fEN_pzLlawTBFoD5V4j2"\ "DMAv80\",\"qi\":\"VFdf8Hg-4ZE9x6AsS9n8YmYvigx2r042LYWLhd3uXHKliAa5DW__jiaqgCmVtwDO3aq97B40SpHZAaVmzUUboFV1Fs8HIcvdtc9yBgWxfOI"\ "-7w-jnskS4o3dZZmw1KVBH_3a_80RUginGr7bUliKdwU_YL15qW4JlQScdQJld9hxEDTKOMHlLvqieRiJpmtLT1-QA_kw2CwbhgVYurAFT-VBpKx6Yn8_85exSWjp"\ "-ciUfR9zqCs6uU-Q5wVdQT6-e8d13KON6L0y5T4p8v6NnN8mKer_uYDHcVnD0SqcDzOkm3FmvBH_3OUx9w71er1p5Ek80UAwRIouE6PXTMiABkA\",\"dp\":\"Xh"\ "1R1QJJLYNUI_XlWaLWIBWpzTpUC523GPj65K7XrUOQaHRqJqh6ggvsF5VaIa7Ny3HEXkfs8qrML_OxibJkUFZX5lLKDhE2Toh7x_Zt9z1mLwwsg1dqoHFLOtqL5IJ"\ "X2na88KjhWzVUCejs4QJB9K3FodNrngI9BXIcyRVRwUt8nWidg1pEB5CgZxxpgyE4ZSD5cS37IPbAQwUPA9GBFcZgoho2VacVYNj99yojyg98ZTfiDz7yb3Yjr7UJ"\ "M0qFfWL1DWAkYRGA8UmmpG0F1ebGHxHAsVrcYAzzEnDh30kHLGq7fsyjjzKqwLOXOfMqcQvSMCtxHfwuer0GymET0oM\",\"dq\":\"HkyTdHy-CQAAgnJzYuC1_F"\ "n6QK2UUXItWST1rHH48tyGaErmtwyqB9Wd8gTktS3cjxEy7zfKObtQvIQWMtLZ7R97enoa4rNBNp442wxukJmLyQOokiqvS-YeXRLJSvduTzHy1-vC05IEzyOEuUL"\ "b6Yxzp54G5kP8RrCnf3DmJgMEamMKDuUM9OzIGnKZAMcnR4ibgDZ8noP6wZXEa-Ec4D7e29eTDGv8q_VuDc-O_VPMTifdLKyYS1pivURpTSHT3RyP4i6hUIGeeAgI"\ "-FDAeTLbtMJgLLsbt2DsDnIAgxVrUxw8y28yLkgiIt-LZBNnIQ6pXe6VCGGDcJGmtCErp4k\",\"kid\":\"4109\"}"; const char jwk_pubkey_rsa_4109_str[] = "{\"kty\":\"RSA\",\"n\":\"GBCMlNgIVKgDhxhYog5r-Qt7KD2GsLRQmQvTImLeqf8VOZzK5cF4vF-N9apBW8MksV29g1vUljCFz1EXrz6EaO30LbC8wa0g-gXam"\ "9pT0QPXOBr2knOHWSCpxVk6ZlVpClOecuy5dvTorZTxNbTtkh4YWlSo5nieAKkZgFR4kQl1DXxpdfGdcXaVfc-QL5npPvwv3Q15aVmiilcAY_-tMw-MACPm6zG6W7P"\ "eilGaH-Y24_E6PMZNA3bxdFQ1do56V1i7DdlH_CZpa2sbv4e5q3mlcg6G0nNN3HqGqIBwkT_Y8Q5vNs2bhzXRDWQjRdouRMs1VZkKJrMX-yZHgKI1xr_LlwnmxLGq1"\ "zWTf6_beiZxmeGRu7tkXKgEaQ8yffokv2o0nI5dKn7U8SWKlRNP-ansyuouaxCWOrIrfjo0ABA6pV_PsBJJ_wOqX0WucYGJANM89LDMC_FPjjqg7Fze8cjMyMFSHBJ"\ "gbWTGD_951iBZhnf69PgfC-AoKNnM4xkib1Xp3_i0o7Al3vJSmBuY5qSn0iLoUcn5SbpEuqZOCwZ6grSzwbyWljSSr_w7vg8mB-RZLvEehR4GQ6lCY17gDB4Ze4trE"\ "4YIvYxDJNde1XIwcaZCVWrtoyC_sbr_OtrDcxetCbnDkmawBX-8idEwZgE8O99s-D2wGH7c2A4iDUFh2w\",\"e\":\"AQAB\",\"kid\":\"4109\"}"; const char jwk_privkey_rsa_1024_str[] = "{\"kty\":\"RSA\",\"n\":\"wXI38cl3dtYLPsV7XC5fEUnV77979stmzsb4ADJiflUZGAppdnJYEDQK3Z5nqtpKP1aPLN0n9rrqWFbQqIMhFMdwSOf10uHy2i0M"\ "jw3oblVZsLG57qYT2T1139XqNFU_nGELfur81ta4dTEPZ_fIa7V9woqX_eqm8GVeW6lDfwE\",\"e\":\"AQAB\",\"d\":\"Y2YYPwIhg4uKba-1qnEdYlnJNw7y"\ "WKa9ZeSxDBDXsUhyw3qeJEGu5GyJZMT_SbguzIriuM_OuCXlQo0hXGU8unUajlIkHqA-OiJb9Jgh1ZTBhD0-pcFnorDNCqPuP9c07EZFlaAFt9xxrC6Ol0_x_ekRP"\ "nGOxEApd85-G_XVH5E\",\"p\":\"xDxOdvrcmknxfBnh-06sCO9iKO6652yhHN3bKjLNQuUFlp_L0g-RCyn4YSZgddXTcnlltgeqmrBqAHOEoR1JvQ\",\"q\":\""\ "_Fxu7icd3mj-0vGawjKhoLydUQaY3_KEYWVerfmeU-aZt01zo2GCYen_IgHAlW_ivxrG-ssD01gg2I-Q400klQ\",\"qi\":\"PG34Ixvyg-V7p4PM-FchaQxmUVU"\ "bpfr4KoSy35a4hmk3Kfcxkrfx_lbhAxdE46u-IBDHBBMH5OXFStNx4xTOXg\",\"dp\":\"TmGMMcf3z4TTeO9ZrSh6XMNJIPJiI0fnfoE7JjrOc_bIaaaAIfJny9"\ "7CwAM1KjvzTlkhADlFsq3eWTnK8xOgvQ\",\"dq\":\"T4oSrJ1HnMIbDwF3dZ3fs3m_W7polK0rbEc3AD6c2HTmHhAbUnN5VMMb1uwWdwM8xF78OC-klQhB0f_t-"\ "rZlwQ\",\"kid\":\"1024\"}"; const char jwk_pubkey_rsa_1024_str[] = "{\"kty\":\"RSA\",\"n\":\"wXI38cl3dtYLPsV7XC5fEUnV77979stmzsb4ADJiflUZGAppdnJYEDQK3Z5nqtpKP1aPLN0n9rrqWFbQqIMhFMdwSOf10uHy2i0Mj"\ "w3oblVZsLG57qYT2T1139XqNFU_nGELfur81ta4dTEPZ_fIa7V9woqX_eqm8GVeW6lDfwE\",\"e\":\"AQAB\",\"kid\":\"1024\"}"; #if NETTLE_VERSION_NUMBER >= 0x030400 START_TEST(test_rhonabwy_parse_token_invalid) { jwe_t * jwe_decrypt; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_decrypt_token_invalid) { jwe_t * jwe_decrypt; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENCRYPTED_KEY, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_IV, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_CIPHER, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_TAG_LEN, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, TOKEN_INVALID_ENC, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_ERROR_PARAM); r_jwk_free(jwk_privkey); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_invalid_privkey) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_ERROR_INVALID); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_small_privkey) { jwe_t * jwe; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_1024_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_eq(r_jwe_serialize(jwe, jwk_pubkey, 0), NULL); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_rsa1_aescbc_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_rsa1_aesgcm_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_pubkey, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_rsa256_aescbc_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_encrypt_decrypt_rsa256_aesgcm_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A256GCM), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, jwk_pubkey, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, jwk_privkey, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_flood_ok) { jwe_t * jwe, * jwe_decrypt; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_decrypt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, NULL, jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe_decrypt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); ck_assert_ptr_ne((token = r_jwe_serialize(jwe, NULL, 0)), NULL); ck_assert_int_eq(r_jwe_parse(jwe_decrypt, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe_decrypt, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe_decrypt->payload, PAYLOAD, jwe_decrypt->payload_len)); o_free(token); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); r_jwe_free(jwe); r_jwe_free(jwe_decrypt); } END_TEST START_TEST(test_rhonabwy_check_key_length_rsa1) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_rsa2048_pub, * jwk_rsa2048_priv, * jwk_rsa4096_pub, * jwk_rsa4096_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_pub, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_pub, jwk_pubkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_priv, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_rsa2048_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_rsa4096_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa2048_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa4096_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa4096_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa2048_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_rsa2048_pub); r_jwk_free(jwk_rsa2048_priv); r_jwk_free(jwk_rsa4096_pub); r_jwk_free(jwk_rsa4096_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_variable_key_length_rsa1) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_rsa1_pub, * jwk_rsa1_priv, * jwk_rsa2_pub, * jwk_rsa2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_rsa1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa1_pub, jwk_pubkey_rsa_3015_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa1_priv, jwk_privkey_rsa_3015_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2_pub, jwk_pubkey_rsa_4109_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2_priv, jwk_privkey_rsa_4109_str), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_rsa1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_RSA_OAEP), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_rsa2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa2_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_rsa1_pub); r_jwk_free(jwk_rsa1_priv); r_jwk_free(jwk_rsa2_pub); r_jwk_free(jwk_rsa2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_variable_key_length_rsa256) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_rsa1_pub, * jwk_rsa1_priv, * jwk_rsa2_pub, * jwk_rsa2_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_rsa1_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa1_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_rsa1_priv, jwk_rsa1_pub, R_KEY_TYPE_RSA, 3015, NULL), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_rsa2_priv, jwk_rsa2_pub, R_KEY_TYPE_RSA, 4109, NULL), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_rsa1_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_rsa2_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa1_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa2_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa2_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa1_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_rsa1_pub); r_jwk_free(jwk_rsa1_priv); r_jwk_free(jwk_rsa2_pub); r_jwk_free(jwk_rsa2_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST START_TEST(test_rhonabwy_check_key_length_rsa256) { jwe_t * jwe_enc_1, * jwe_enc_2, * jwe_dec_1, * jwe_dec_2; jwk_t * jwk_rsa2048_pub, * jwk_rsa2048_priv, * jwk_rsa4096_pub, * jwk_rsa4096_priv; char * token_1, * token_2; ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa2048_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_pub), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_rsa4096_priv), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_1), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe_enc_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_pub, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa2048_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_pub, jwk_pubkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_rsa4096_priv, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_1, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_1, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_1, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_1 = r_jwe_serialize(jwe_enc_1, jwk_rsa2048_pub, 0)), NULL); ck_assert_int_eq(r_jwe_set_payload(jwe_enc_2, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwe_set_alg(jwe_enc_2, R_JWA_ALG_RSA_OAEP_256), RHN_OK); ck_assert_int_eq(r_jwe_set_enc(jwe_enc_2, R_JWA_ENC_A256CBC), RHN_OK); ck_assert_ptr_ne((token_2 = r_jwe_serialize(jwe_enc_2, jwk_rsa4096_pub, 0)), NULL); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa2048_priv, 0), RHN_OK); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa4096_priv, 0), RHN_OK); r_jwe_free(jwe_dec_2); ck_assert_ptr_ne((jwe_dec_1 = r_jwe_quick_parse(token_1, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_1, jwk_rsa4096_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_1); ck_assert_ptr_ne((jwe_dec_2 = r_jwe_quick_parse(token_2, R_PARSE_NONE, 0)), NULL); ck_assert_int_eq(r_jwe_decrypt(jwe_dec_2, jwk_rsa2048_priv, 0), RHN_ERROR_INVALID); r_jwe_free(jwe_dec_2); r_jwk_free(jwk_rsa2048_pub); r_jwk_free(jwk_rsa2048_priv); r_jwk_free(jwk_rsa4096_pub); r_jwk_free(jwk_rsa4096_priv); r_jwe_free(jwe_enc_1); r_jwe_free(jwe_enc_2); r_free(token_1); r_free(token_2); } END_TEST /** * Test decrypting the JWE in the RFC 7516 * A.2. Example JWE using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 * https://tools.ietf.org/html/rfc7516#page-36 */ START_TEST(test_rhonabwy_decrypt_rfc_ok) { const char token[] = "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.\ OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe\ ipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDb\ Sv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaV\ mqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je8\ 1860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi\ 6UklfCpIMfIjf7iGdXKHzg.\ 48V1_ALb6US04U3b.\ 5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6ji\ SdiwkIr3ajwQzaBtQD_A.\ XFBoMYUZodetZdvTiFvSkQ", privkey[] = "{\"kty\":\"RSA\",\ \"n\":\"oahUIoWw0K0usKNuOR6H4wkf4oBUXHTxRvgb48E-BVvxkeDNjbC4he8rUW\ cJoZmds2h7M70imEVhRU5djINXtqllXI4DFqcI1DgjT9LewND8MW2Krf3S\ psk_ZkoFnilakGygTwpZ3uesH-PFABNIUYpOiN15dsQRkgr0vEhxN92i2a\ sbOenSZeyaxziK72UwxrrKoExv6kc5twXTq4h-QChLOln0_mtUZwfsRaMS\ tPs6mS6XrgxnxbWhojf663tuEQueGC-FCMfra36C9knDFGzKsNa7LZK2dj\ YgyD3JR_MB_4NUJW_TqOQtwHYbxevoJArm-L5StowjzGy-_bq6Gw\",\ \"e\":\"AQAB\",\ \"d\":\"kLdtIj6GbDks_ApCSTYQtelcNttlKiOyPzMrXHeI-yk1F7-kpDxY4-WY5N\ WV5KntaEeXS1j82E375xxhWMHXyvjYecPT9fpwR_M9gV8n9Hrh2anTpTD9\ 3Dt62ypW3yDsJzBnTnrYu1iwWRgBKrEYY46qAZIrA2xAwnm2X7uGR1hghk\ qDp0Vqj3kbSCz1XyfCs6_LehBwtxHIyh8Ripy40p24moOAbgxVw3rxT_vl\ t3UVe4WO3JkJOzlpUf-KTVI2Ptgm-dARxTEtE-id-4OJr0h-K-VFs3VSnd\ VTIznSxfyrj8ILL6MG_Uv8YAu7VILSB3lOW085-4qE3DzgrTjgyQ\",\ \"p\":\"1r52Xk46c-LsfB5P442p7atdPUrxQSy4mti_tZI3Mgf2EuFVbUoDBvaRQ-\ SWxkbkmoEzL7JXroSBjSrK3YIQgYdMgyAEPTPjXv_hI2_1eTSPVZfzL0lf\ fNn03IXqWF5MDFuoUYE0hzb2vhrlN_rKrbfDIwUbTrjjgieRbwC6Cl0\",\ \"q\":\"wLb35x7hmQWZsWJmB_vle87ihgZ19S8lBEROLIsZG4ayZVe9Hi9gDVCOBm\ UDdaDYVTSNx_8Fyw1YYa9XGrGnDew00J28cRUoeBB_jKI1oma0Orv1T9aX\ IWxKwd4gvxFImOWr3QRL9KEBRzk2RatUBnmDZJTIAfwTs0g68UZHvtc\",\ \"dp\":\"ZK-YwE7diUh0qR1tR7w8WHtolDx3MZ_OTowiFvgfeQ3SiresXjm9gZ5KL\ hMXvo-uz-KUJWDxS5pFQ_M0evdo1dKiRTjVw_x4NyqyXPM5nULPkcpU827\ rnpZzAJKpdhWAgqrXGKAECQH0Xt4taznjnd_zVpAmZZq60WPMBMfKcuE\",\ \"dq\":\"Dq0gfgJ1DdFGXiLvQEZnuKEN0UUmsJBxkjydc3j4ZYdBiMRAy86x0vHCj\ ywcMlYYg4yoC4YZa9hNVcsjqA3FeiL19rk8g6Qn29Tt0cj8qqyFpz9vNDB\ UfCAiJVeESOjJDZPYHdHY8v1b-o-Z2X5tvLx-TCekf7oxyeKDUqKWjis\",\ \"qi\":\"VIMpMYbPf47dT1w_zDUXfPimsSegnMOA1zTaX7aGk_8urY6R8-ZW1FxU7\ AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3\ eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY\"}", plaintext[] = "The true sign of intelligence is not knowledge but imagination."; jwe_t * jwe; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, privkey), RHN_OK); ck_assert_int_eq(r_jwe_add_keys(jwe, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, token, 0), RHN_OK); ck_assert_int_eq(r_jwe_decrypt(jwe, NULL, 0), RHN_OK); ck_assert_int_eq(0, memcmp(jwe->payload, plaintext, jwe->payload_len)); r_jwk_free(jwk_privkey); r_jwe_free(jwe); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWE RSA OAEP key encryption tests"); tc_core = tcase_create("test_rhonabwy_rsa_oaep"); #if NETTLE_VERSION_NUMBER >= 0x030400 tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_token_invalid); tcase_add_test(tc_core, test_rhonabwy_encrypt_small_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_invalid_privkey); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_rsa1_aescbc_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_rsa1_aesgcm_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_rsa256_aescbc_ok); tcase_add_test(tc_core, test_rhonabwy_encrypt_decrypt_rsa256_aesgcm_ok); tcase_add_test(tc_core, test_rhonabwy_flood_ok); tcase_add_test(tc_core, test_rhonabwy_check_key_length_rsa1); tcase_add_test(tc_core, test_rhonabwy_check_key_length_rsa256); tcase_add_test(tc_core, test_rhonabwy_variable_key_length_rsa1); tcase_add_test(tc_core, test_rhonabwy_variable_key_length_rsa256); tcase_add_test(tc_core, test_rhonabwy_decrypt_rfc_ok); #endif tcase_set_timeout(tc_core, 90); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWE RSA OAEP key encryption tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwk_core.c000066400000000000000000001262531452472117100163710ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_rsa_x5u_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\",\"x5u\":\"https://www.example.com/x509\"}"; const char jwk_pubkey_rsa_x5c_str[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2"\ "yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quG"\ "mFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPp"\ "njL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0\",\"e\":\"AQAB\",\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"]}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2020-03-13\"}"; const char jwk_pubkey_rsa_2_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX" "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6" "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\"" ",\"e\":\"AQAB\",\"kid\":\"rTIyDPbFltiEsFOBulc6uo3dV0m03o9KI6efmondrrI\"}"; const char jwk_pubkey_rsa_2_pem[] = "-----BEGIN PUBLIC KEY-----"\ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0vx7agoebGcQSuuPiLJX"\ "ZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tS"\ "oc/BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ/2W+5JsGY4Hc5n9yBXArwl93lqt"\ "7/RN5w6Cf0h4QyQ5v+65YGjQR0/FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0"\ "zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt+bFTWhAI4vMQFh6WeZu0f"\ "M4lFd2NcRwr3XPksINHaQ+G/xBniIqbw0Ls1jF44+csFCur+kEgU8awapJzKnqDK"\ "gwIDAQAB"\ "-----END PUBLIC KEY-----"; const char jwk_pubkey_rsa_3_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_3_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; #if GNUTLS_VERSION_NUMBER >= 0x030600 const char jwk_pubkey_ecdsa_2_str[] = "{\"kty\":\"EC\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\",\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\"," "\"crv\":\"P-256\",\"kid\":\"UblEzfpUTUwyc6pr81BiWn3VO7tqcXIydPU4sZogd2A\"}"; const char jwk_pubkey_ecdsa_2_pem[] = "-----BEGIN PUBLIC KEY-----\n"\ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMKBCTNIcKUSDii11ySs3526iDZ8A\n"\ "iTo7Tu6KPAqv7D7gS2XpJFbZiItSs3m9+9Ue6GnvHw/GW2ZZaVtszggXIw==\n"\ "-----END PUBLIC KEY-----\n"; #endif const char jwk_key_symmetric[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0\"}"; const char jwk_from_rfc[] = "{\ \"kty\": \"RSA\",\ \"n\": \"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt\ VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6\ 4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD\ W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9\ 1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH\ aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\",\ \"e\": \"AQAB\",\ \"alg\": \"RS256\",\ \"kid\": \"2011-04-29\"\ }"; const char jwk_from_frc_thumb[] = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"; #define KID "kid_1" START_TEST(test_rhonabwy_init) { jwk_t * jwk; ck_assert_int_eq(r_jwk_init(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_get_property) { jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kty"), "EC"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "crv"), "P-256"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "x"), "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "y"), "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "use"), "enc"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kid"), "1"); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, ""), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, NULL), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(NULL, "kty"), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "error"), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kty"), "RSA"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "n"), "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "e"), "AQAB"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "alg"), "RS256"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kid"), "2011-04-29"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "x5u"), "https://www.example.com/x509"); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kty"), "RSA"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "use"), "sig"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kid"), "1b94c"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "n"), "AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2"\ "yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quG"\ "mFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPp"\ "njL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "e"), "AQAB"); ck_assert_str_eq(r_jwk_get_property_array(jwk, "x5c", 0), "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); ck_assert_ptr_eq(r_jwk_get_property_array(jwk, "x5c", 1), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "x5c"), NULL); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_set_property) { jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_set_property_str(NULL, "kid", "42"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_str(jwk, "", "42"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_str(jwk, NULL, "42"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_str(jwk, "kid", ""), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_str(jwk, "kid", NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_str(jwk, "kid", "42"), RHN_OK); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kty"), "EC"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "crv"), "P-256"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "x"), "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "y"), "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "use"), "enc"); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kid"), "42"); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, ""), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, NULL), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(NULL, "kty"), NULL); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "error"), NULL); ck_assert_int_eq(r_jwk_set_property_str(jwk, "x", ";error;"), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_str_eq(r_jwk_get_property_array(jwk, "x5c", 0), "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); ck_assert_int_eq(r_jwk_set_property_array(jwk, "x5c", 1, "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_set_property_array(jwk, "x5c", 0, "GIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="), RHN_OK); ck_assert_str_eq(r_jwk_get_property_array(jwk, "x5c", 0), "GIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); ck_assert_int_eq(r_jwk_append_property_array(jwk, "x5c", "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="), RHN_OK); ck_assert_str_eq(r_jwk_get_property_array(jwk, "x5c", 0), "GIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); ck_assert_str_eq(r_jwk_get_property_array(jwk, "x5c", 1), "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_delete_property) { jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_str_eq(r_jwk_get_property_str(jwk, "kty"), "EC"); ck_assert_int_eq(r_jwk_delete_property_str(jwk, ""), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_delete_property_str(jwk, NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_delete_property_str(NULL, "kty"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_delete_property_str(jwk, "kty"), RHN_OK); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "kty"), NULL); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_generate_key_pair) { jwk_t * jwk_privkey, * jwk_pubkey; unsigned int bits = 0; int type; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(NULL, jwk_pubkey, R_KEY_TYPE_RSA, 4096, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, NULL, R_KEY_TYPE_RSA, 4096, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, 0, 4096, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_RSA, 0, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_RSA, 4096, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_privkey, "kid")); ck_assert_int_ne((type = r_jwk_key_type(jwk_privkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 4096); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 4096); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_RSA, 4096, NULL), RHN_OK); ck_assert_str_ne(KID, r_jwk_get_property_str(jwk_privkey, "kid")); ck_assert_int_ne((type = r_jwk_key_type(jwk_privkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 4096); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); ck_assert_str_ne(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 4096); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_EC, 1, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_EC, 555, KID), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_EC, 521, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_privkey, "kid")); ck_assert_str_eq("P-521", r_jwk_get_property_str(jwk_privkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_privkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 521); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_str_eq("P-521", r_jwk_get_property_str(jwk_pubkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 521); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_EDDSA, 256, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_str_eq("Ed25519", r_jwk_get_property_str(jwk_pubkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #if GNUTLS_VERSION_NUMBER >= 0x03060e ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_EDDSA, 448, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_str_eq("Ed448", r_jwk_get_property_str(jwk_pubkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 448); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_ECDH, 256, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_str_eq("X25519", r_jwk_get_property_str(jwk_pubkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_ne(type & R_KEY_TYPE_ECDH, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_generate_key_pair(jwk_privkey, jwk_pubkey, R_KEY_TYPE_ECDH, 448, KID), RHN_OK); ck_assert_str_eq(KID, r_jwk_get_property_str(jwk_pubkey, "kid")); ck_assert_str_eq("X448", r_jwk_get_property_str(jwk_pubkey, "crv")); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 448); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_ne(type & R_KEY_TYPE_ECDH, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #endif #endif } END_TEST START_TEST(test_rhonabwy_equal) { jwk_t * jwk1, * jwk2; ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_ne(r_jwk_equal(jwk1, jwk2), 0); r_jwk_set_property_str(jwk2, "kid", "2"); ck_assert_int_eq(r_jwk_equal(jwk1, jwk2), 0); r_jwk_free(jwk1); r_jwk_free(jwk2); } END_TEST START_TEST(test_rhonabwy_copy) { jwk_t * jwk1, * jwk2 = NULL; ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_equal(jwk1, jwk2), 0); ck_assert_ptr_ne((jwk2 = r_jwk_copy(jwk1)), NULL); ck_assert_int_ne(r_jwk_equal(jwk1, jwk2), 0); r_jwk_free(jwk1); r_jwk_free(jwk2); } END_TEST START_TEST(test_rhonabwy_thumb) { jwk_t * jwk1, * jwk2 = NULL; char * thumb1, * thumb2, * thumb3; ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_ptr_eq(NULL, r_jwk_thumbprint(NULL, 42, 0)); ck_assert_ptr_eq(NULL, r_jwk_thumbprint(NULL, R_JWK_THUMB_SHA256, 0)); ck_assert_ptr_eq(NULL, r_jwk_thumbprint(jwk1, 42, 0)); // Compare 2 equivalent keys, one with more optional properties ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_ptr_ne(NULL, (thumb2 = r_jwk_thumbprint(jwk2, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq(thumb1, thumb2); r_free(thumb1); r_free(thumb2); r_jwk_free(jwk1); r_jwk_free(jwk2); // Compare 2 equivalent RSA keys, one in PEM format, one in jwk format ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_rsa_2_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk2, R_X509_TYPE_PUBKEY, R_FORMAT_PEM, (const unsigned char *)jwk_pubkey_rsa_2_pem, o_strlen(jwk_pubkey_rsa_2_pem)), RHN_OK); ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_ptr_ne(NULL, (thumb2 = r_jwk_thumbprint(jwk2, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq(thumb1, thumb2); r_jwk_free(jwk1); r_jwk_free(jwk2); r_free(thumb1); r_free(thumb2); #if GNUTLS_VERSION_NUMBER >= 0x030600 // Compare 2 equivalent ecdsa keys, one in PEM format, one in jwk format ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_ecdsa_2_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk2, R_X509_TYPE_PUBKEY, R_FORMAT_PEM, (const unsigned char *)jwk_pubkey_ecdsa_2_pem, o_strlen(jwk_pubkey_ecdsa_2_pem)), RHN_OK); ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_ptr_ne(NULL, (thumb2 = r_jwk_thumbprint(jwk2, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq(thumb1, thumb2); r_free(thumb1); r_free(thumb2); r_jwk_free(jwk1); r_jwk_free(jwk2); #endif // Test SHA256, SHA384 and SHA512 thumbprints ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_rsa_str), RHN_OK); ck_assert_str_eq("NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq("R9_OfJjSjaw8Fuum86UzK5ixTdN9bo9BaqPSiseq89DWfmqCdpSgUHus-cxDUNc8", (thumb2 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA384, 0))); ck_assert_str_eq("DpvEwocfn3FjeWWQjcJHzWrpKTIymKwgoL1xVgQcud48-qZDSRCr1zfWZQdHAJn_ciqXqPTSARyg-L-NyNGpVA", (thumb3 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA512, 0))); r_free(thumb1); r_free(thumb2); r_free(thumb3); r_jwk_free(jwk1); // Test symmetric key thumb ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_key_symmetric), RHN_OK); ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); r_free(thumb1); r_jwk_free(jwk1); // Test key thumbprint example in the RFC ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_from_rfc), RHN_OK); ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq(thumb1, jwk_from_frc_thumb); r_free(thumb1); r_jwk_free(jwk1); // Compare 2 keys, one private, one public ck_assert_int_eq(r_jwk_init(&jwk1), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk2), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk1, jwk_pubkey_rsa_3_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk2, jwk_privkey_rsa_3_str), RHN_OK); ck_assert_ptr_ne(NULL, (thumb1 = r_jwk_thumbprint(jwk1, R_JWK_THUMB_SHA256, 0))); ck_assert_ptr_ne(NULL, (thumb2 = r_jwk_thumbprint(jwk2, R_JWK_THUMB_SHA256, 0))); ck_assert_str_eq(thumb1, thumb2); r_free(thumb1); r_free(thumb2); r_jwk_free(jwk1); r_jwk_free(jwk2); } END_TEST START_TEST(test_rhonabwy_match) { jwk_t * jwk; json_t * j_match; const char match_empty[] = "{}", match_invalid[] = "error", match_kty_rsa[] = "{\"kty\":\"RSA\"}", match_kty_ec[] = "{\"kty\":\"EC\"}", match_kty_rsa_alg_rs256[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\"}", match_kty_rsa_n[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX" "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6" "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\"}", match_kty_rsa_alg_ps256[] = "{\"kty\":\"RSA\",\"alg\":\"PS256\"}"; ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_rsa_str)); ck_assert_int_eq(RHN_ERROR_PARAM, r_jwk_match_json_str(jwk, match_empty)); ck_assert_int_eq(RHN_ERROR_PARAM, r_jwk_match_json_str(jwk, match_invalid)); ck_assert_ptr_ne(NULL, j_match = json_loads(match_kty_rsa, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(RHN_OK, r_jwk_match_json_t(jwk, j_match)); json_decref(j_match); ck_assert_int_eq(RHN_OK, r_jwk_match_json_str(jwk, match_kty_rsa)); ck_assert_int_eq(RHN_ERROR_INVALID, r_jwk_match_json_str(jwk, match_kty_ec)); ck_assert_int_eq(RHN_OK, r_jwk_match_json_str(jwk, match_kty_rsa_alg_rs256)); ck_assert_int_eq(RHN_ERROR_INVALID, r_jwk_match_json_str(jwk, match_kty_rsa_alg_ps256)); ck_assert_int_eq(RHN_OK, r_jwk_match_json_str(jwk, match_kty_rsa_n)); r_jwk_free(jwk); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWK core function tests"); tc_core = tcase_create("test_rhonabwy_core"); tcase_add_test(tc_core, test_rhonabwy_init); tcase_add_test(tc_core, test_rhonabwy_get_property); tcase_add_test(tc_core, test_rhonabwy_set_property); tcase_add_test(tc_core, test_rhonabwy_delete_property); tcase_add_test(tc_core, test_rhonabwy_generate_key_pair); tcase_add_test(tc_core, test_rhonabwy_equal); tcase_add_test(tc_core, test_rhonabwy_copy); tcase_add_test(tc_core, test_rhonabwy_thumb); tcase_add_test(tc_core, test_rhonabwy_match); tcase_set_timeout(tc_core, 90); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWK core tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwk_export.c000066400000000000000000001363741452472117100167670ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_pem[] = "-----BEGIN PUBLIC KEY-----\n"\ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMKBCTNIcKUSDii11ySs3526iDZ8A\n"\ "iTo7Tu6KPAqv7D7gS2XpJFbZiItSs3m9+9Ue6GnvHw/GW2ZZaVtszggXIw==\n"\ "-----END PUBLIC KEY-----\n"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_pem[] = "-----BEGIN EC PRIVATE KEY-----\n"\ "MHgCAQEEIQDzvQwHqB+5Mnge1SdS9gzImmvl5Rk0/gGTjdtV2Pd4AaAKBggqhkjO\n"\ "PQMBB6FEA0IABDCgQkzSHClEg4otdckrN+duog2fAIk6O07uijwKr+w+4Etl6SRW\n"\ "2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM=\n"\ "-----END EC PRIVATE KEY-----\n"; const char jwk_privkey_eddsa_str[] = "{\"kty\":\"OKP\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\","\ "\"d\":\"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A\",\"kid\":\"moimeme\"}"; const char jwk_privkey_eddsa_pem[] = "-----BEGIN UNKNOWN-----\n" "MFECAQEEIJ1hsZ3v/VpguoRK9JLsLMREScVpezJpGXA7rAMcrn9goAUGAytlcKEj\n" "AyEA11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=\n" "-----END UNKNOWN-----\n"; const char jwk_privkey_ecdh_str[] = "{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo\"," "\"d\":\"RVqkt2ZmEiUY-OGyag9rXe7vsDm2BQ_XykdxhLv9pd4\"}"; #if 0 const char jwk_pubkey_secp256k1_str[] = "{\"crv\":\"secp256k1\",\"kid\":\"JUvpllMEYUZ2joO59UNui_XYDqxVqiFLLAJ8klWuPBw\",\"kty\":\"EC\"," "\"x\":\"dWCvM4fTdeM0KmloF57zxtBPXTOythHPMm1HCLrdd3A\",\"y\":\"36uMVGM7hnw-N6GnjFcihWE3SkrhMLzzLCdPMXPEXlA\"}"; #endif const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_pem[] = "-----BEGIN PUBLIC KEY-----\n"\ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0vx7agoebGcQSuuPiLJX\n"\ "ZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tS\n"\ "oc/BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ/2W+5JsGY4Hc5n9yBXArwl93lqt\n"\ "7/RN5w6Cf0h4QyQ5v+65YGjQR0/FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0\n"\ "zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt+bFTWhAI4vMQFh6WeZu0f\n"\ "M4lFd2NcRwr3XPksINHaQ+G/xBniIqbw0Ls1jF44+csFCur+kEgU8awapJzKnqDK\n"\ "gwIDAQAB\n"\ "-----END PUBLIC KEY-----\n"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"\ "MIIEowIBAAKCAQEA0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78L\n"\ "hWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc/BJECPebWKRXjBZCiFV4n3oknj\n"\ "hMstn64tZ/2W+5JsGY4Hc5n9yBXArwl93lqt7/RN5w6Cf0h4QyQ5v+65YGjQR0/F\n"\ "DW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbO\n"\ "pbISD08qNLyrdkt+bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ+G/xBni\n"\ "Iqbw0Ls1jF44+csFCur+kEgU8awapJzKnqDKgwIDAQABAoIBAF+HE7XiWP4J+BWD\n"\ "7FwfK3V4seb8LINRSzeRNxGhukSaFR/hyyyg/TO3ceaKOxlEZJ3IZ60cHlJAu4U+\n"\ "XySzNFmxQCjS1mNr7+wejal0s1L8U9P2En6oo8Kd0U85QWgsVqeHaBZOTdqPBsv5\n"\ "xzSq6AAyJCeOqUVKIbF8sG0XgHWGjMBbPbb/Hf3D1WN4tO2t7fDDekzcJtHUmsJv\n"\ "b+O1Igpd0pOWYhu8aIzy7uLG4NVNo8eCAUzQc52yUsxRyuuo0/G4JLqrJNBo7JAy\n"\ "ZNfWeKsI8G7J5+I9lgYot0S/lLNpRlZGPH5Bc5ntc9B2yJH89GOpqpzmLanNF+I3\n"\ "3CqAAvECgYEA83i+7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxt\n"\ "PVnwD20R+60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQy\n"\ "qVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfsCgYEA3dfO\n"\ "R9cuYq+0S+mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgT\n"\ "nCdpYzBcOfW5r370AFXjiWft/NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ+1k\n"\ "Yd/s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxkCgYAbiw9eRzphr3Lyglb38guP\n"\ "jG6mm7SXOL8ftVORLzGPlJ1fdygTSiKZjDEiLZ6ZMC57RQ5rl2mAUbIEnhzy1DZU\n"\ "XjTZdG6AoNM/xqRiEWjm0ADvtB782a25hlzcLebcjbgbYa9HmxIPFTIA3bOrwt+f\n"\ "0RSazqtjc5vxh6IqROIGPQKBgQCz2UAf1+CAGygVHw5pzZH8TaDDbzatPaQY4CG8\n"\ "iWURMTV5+sDqG5RS8x8FwymfyWp5bq/POdhjlJJAXukx0L9qAjecbwhunUFRvQlS\n"\ "KtpE2pR8uFxBv930YXgOHt7vhZtGyhtGie6NNg3XEJo/pM7rWO9atf4vXy3FfDj3\n"\ "hD9yCQKBgBsjP6eia18kos9baBYCm1lfiXSN40OMqbva2zFsd60CQX5rdBaGM4FC\n"\ "GRFRRHDqsHpkTfNc6AwGmvgZNCljRg4yR2Q3Q5hYVtwDe5SPqbsZP5h2Ridda8ck\n"\ "fDueVy0nt0j5kXysGSOslNuGcb0ChWCLXZXVChszuiGus0yoQFUV\n"\ "-----END RSA PRIVATE KEY-----\n"; #define KEY_DECODED "secret" const char jwk_key_symmetric[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0\"}"; const char jwk_pubkey_rsa_x5c_str[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2"\ "yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quG"\ "mFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPp"\ "njL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0\",\"e\":\"AQAB\",\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"]}"; const char jwk_pubkey_rsa_x5u_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\",\"x5u\":\"https://www.example.com/x509\"}"; const char jwk_pubkey_rsa_x5u_only_rsa_pub_7465[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_rsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_ecdsa_pub_7465[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_ecdsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_large_7465[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_large\"}"; const char jwk_pubkey_rsa_x5u_only_rsa_pub_7466[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7466/x5u_rsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_ecdsa_pub_7466[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7466/x5u_ecdsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_large_7466[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7466/x5u_large\"}"; const char jwk_pubkey_rsa_x5u_only_rsa_pub_7467[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7467/x5u_rsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_ecdsa_pub_7467[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7467/x5u_ecdsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_large_7467[] = "{\"kty\":\"EC\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7467/x5u_large\"}"; const char jwk_pubkey_rsa_x5u_export[] = "-----BEGIN PUBLIC KEY-----\n"\ "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsUWjL3wK1B/dQbXbhSXa\n"\ "odF0gXMNlZg3ZecjZIJOKgXGDVOnV0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul\n"\ "9kyzpPBr53ELHMmAeI/I1rnF4pgIwfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHh\n"\ "tST9V874mMehsSUG4xM2qiBvvbWwX0KCyKk6BY/CdyljUjAPUShcVysKUTyfefew\n"\ "38KUVTVpk2vWLlN+a41iC/gxGvLtH142LDiDx/s+Kh37f4paD2zsEw5McF81eiKT\n"\ "AfrraIC1Gj2BxyEj6n2EjqyI+NFRsSUmqfPoFgiMzlEWj4P8AwvfE9jbjXz/E0GO\n"\ "ISiXt4L+06U7rLoGHFri5oVI6KUkLAOwwwTri+ikeQFx68IKvhytBiX1O+XHh51J\n"\ "ZyyC+fcKKN+/ATgGKIiR63M5UWYxO2JkVkPvpzORKJUivePFQbkEcxYZb9VqoVZ0\n"\ "4sfpfGb3h2douzBrKbkDP/Jf+O0JPKDTltrUJOpZbYhVAgMBAAE=\n"\ "-----END PUBLIC KEY-----\n"; const char jwk_pubkey_ecdsa_x5u_export[] = "-----BEGIN PUBLIC KEY-----\n"\ "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6N6hUatqySn6NrHxNM5fL3ajo8YY\n"\ "3ZOXdeyGo39dmd+TLHEvEq8nSKB9DhDLj/3Dw8aNWKWdjjNHfLblUnsotw==\n"\ "-----END PUBLIC KEY-----\n"; const unsigned char rsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIEWTCCAsGgAwIBAgIUJyAFwqkMTppNiyU8gFOK4WUC1GgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0xOTEyMDYxMzU1MzlaFw0yMDExMjAxMzU1MzlaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MIIBojANBgkqhkiG9w0BAQEFAAOC\n" "AY8AMIIBigKCAYEAsUWjL3wK1B/dQbXbhSXaodF0gXMNlZg3ZecjZIJOKgXGDVOn\n" "V0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul9kyzpPBr53ELHMmAeI/I1rnF4pgI\n" "wfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHhtST9V874mMehsSUG4xM2qiBvvbWw\n" "X0KCyKk6BY/CdyljUjAPUShcVysKUTyfefew38KUVTVpk2vWLlN+a41iC/gxGvLt\n" "H142LDiDx/s+Kh37f4paD2zsEw5McF81eiKTAfrraIC1Gj2BxyEj6n2EjqyI+NFR\n" "sSUmqfPoFgiMzlEWj4P8AwvfE9jbjXz/E0GOISiXt4L+06U7rLoGHFri5oVI6KUk\n" "LAOwwwTri+ikeQFx68IKvhytBiX1O+XHh51JZyyC+fcKKN+/ATgGKIiR63M5UWYx\n" "O2JkVkPvpzORKJUivePFQbkEcxYZb9VqoVZ04sfpfGb3h2douzBrKbkDP/Jf+O0J\n" "PKDTltrUJOpZbYhVAgMBAAGjdjB0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYI\n" "KwYBBQUHAwIwDwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUiZGaRSyAyraAdeo5\n" "wJc+0Ks7IOcwHwYDVR0jBBgwFoAU0marYk/GnTVDeDbie2BY15qCu0QwDQYJKoZI\n" "hvcNAQELBQADggGBAGINVR+lskHnxkYvPkgCQG+nGqovI28W6rtx8a5xM/6rtsVs\n" "5jCu1nnJd32YNjDsySxsbkhXjW0WjGR7cEsnmcOITeP4kLLVzh1vm6sZa/9vX1fh\n" "M5pTUTYTHYozl6TA85CtBd7oC/AB2Gwh5q1kJ3wmGwmCY8mqPftP+plyFTSbCwAH\n" "BZSfCgsMpffILDzPgViU54BehfpfljZcmGJnnGKEnTRvUr84/NlmKEdhw9rKyod5\n" "KKieGneVzpPeiyXrzUEJuGkmLtVLpvNdDdB5+6rN0hK+bFyB3NA+gASIiekuM7Q+\n" "4RgroWwTF7fq1XUhX3aexOI2eTx0B2bBpD28TcYvqo6Y+aBKHVbo8gnbMr5IoIkI\n" "rYz8CXrbbZFRilsHRQgzyEmTq/Wp0GVt/zakMF7suA8nl/AQcKDOWGBnEFc+okAe\n" "K0P/4R4UnQSPU8SfsFBGxm4PXN4BZktZ10LC/xKMJBkdSD0vTLce9Sx7xR4PUIaN\n" "n2x0D4zZG7px73kB0Q==\n" "-----END CERTIFICATE-----"; const unsigned char ecdsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIDNjCCAZ6gAwIBAgIUDzxOEj+8WUrLa1M97arwkEo5gEwwDQYJKoZIhvcNAQEL\n" "BQAwMjEbMBkGA1UEAwwSZ2xld2x3eWRfcGFja2VkX2NhMRMwEQYDVQQKEwpiYWJl\n" "bG91ZXN0MB4XDTE5MTIwNjEzNTYxM1oXDTIwMTEyMDEzNTYxM1owYDEYMBYGA1UE\n" "AwwPZ2xld2x3eWRfcGFja2VkMSIwIAYDVQQLExlBdXRoZW50aWNhdG9yIEF0dGVz\n" "dGF0aW9uMRMwEQYDVQQKEwpiYWJlbG91ZXN0MQswCQYDVQQGEwJDQTBZMBMGByqG\n" "SM49AgEGCCqGSM49AwEHA0IABOjeoVGraskp+jax8TTOXy92o6PGGN2Tl3XshqN/\n" "XZnfkyxxLxKvJ0igfQ4Qy4/9w8PGjVilnY4zR3y25VJ7KLejYTBfMAwGA1UdEwEB\n" "/wQCMAAwDwYDVR0PAQH/BAUDAweAADAdBgNVHQ4EFgQU34GPDg2bLIneLKIfjYjU\n" "NuiU170wHwYDVR0jBBgwFoAUlOaykWFTL+EV/0PHksB2Dh1k1KAwDQYJKoZIhvcN\n" "AQELBQADggGBAFHNuUQUkZaunXfV3qSemhlyHH1hnt6YXJLIl2IKugg/mg8hga2C\n" "dBN7MMcVYpXtNI8AKfSIZRu3v16OMIajCIh7PYGa5asbJZgtOkbvfc58eaWhzl8U\n" "B0j89aGlntZs3WWINYgqfzBS6Pw3SJ5iVTpS+xH2JSWxZYX3uvEDkVkw1VjmyyN3\n" "ZX0tkFTKQB3GNFZwesxoRKizsu8r+tCIqgfqRTG7FIOa/UB3MXVClA//+TCnW2RI\n" "48JzjY/YhO54pWVsblHAQwMOmuHlJrnfLFPvBqFx5mi8Z5jHfZipsNksIteKFdtG\n" "3FvjQYIj2wJM9k7XHrQ3szxwvq9Ss2cyCBPArrKVpBTibypIkON9R2Peocr3HkUx\n" "YYhu3pNumaSdGzL0r7A2iGIXy9orIAQ8f1i7iaYDBWs/PkJ340iHRZtSuez8F+GN\n" "NUV15utv9AMvahkCI5ZS71TAv4AFjsZpsvYuCvpUUPdZpC+r9lk8H1wa4VA+mujL\n" "2Yxh1fFV7ONNjA==\n" "-----END CERTIFICATE-----"; #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_x5u_rsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)rsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)ecdsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_large (const struct _u_request * request, struct _u_response * response, void * user_data) { char * large_body = o_malloc((6*1024*1024)); memset(large_body, ' ', (6*1024*1024)); o_strcpy(large_body, (const char *)ecdsa_crt); ulfius_set_binary_body_response(response, 200, (const char *)large_body, (6*1024*1024)); o_free(large_body); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_export_to_str) { jwk_t * jwk; char * export_str; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"EC\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"crv\":\"P-256\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"use\":\"enc\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"1\""), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"EC\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"crv\":\"P-256\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"use\":\"enc\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"1\""), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_eddsa_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"OKP\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"crv\":\"Ed25519\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"d\":\"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"use\":\"sig\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"moimeme\""), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"RSA\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"e\":\"AQAB\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"alg\":\"RS256\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"2011-04-29\""), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"oct\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"alg\":\"HS256\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"k\":\"c2VjcmV0\""), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"RSA\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"use\":\"sig\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"1b94c\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"n\":\"AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K"\ "-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1M"\ "tcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"e\":\"AQAB\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"]"), NULL); o_free(export_str); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_ptr_ne((export_str = r_jwk_export_to_json_str(jwk, 0)), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kty\":\"RSA\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"e\":\"AQAB\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"alg\":\"RS256\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"kid\":\"2011-04-29\""), NULL); ck_assert_ptr_ne(o_strstr(export_str, "\"x5u\":\"https://www.example.com/x509\""), NULL); o_free(export_str); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_export_to_json) { jwk_t * jwk; json_t * j_export; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_json_t(jwk), NULL); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "EC"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "crv")), "P-256"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "y")), "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "use")), "enc"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kid")), "1"); json_decref(j_export); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "EC"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "crv")), "P-256"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "y")), "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "d")), "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "use")), "enc"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kid")), "1"); json_decref(j_export); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "RSA"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "n")), "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "e")), "AQAB"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "alg")), "RS256"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kid")), "2011-04-29"); json_decref(j_export); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "oct"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "alg")), "HS256"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "k")), "c2VjcmV0"); json_decref(j_export); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "RSA"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "use")), "sig"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kid")), "1b94c"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "n")), "AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2y"\ "vz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_"\ "A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgH"\ "IXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6Z"\ "QqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW"\ "-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "e")), "AQAB"); ck_assert_int_eq(json_is_array(json_object_get(j_export, "x5c")), 1); ck_assert_int_eq(json_array_size(json_object_get(j_export, "x5c")), 1); ck_assert_int_eq(json_is_string(json_array_get(json_object_get(j_export, "x5c"), 0)), 1); ck_assert_str_eq(json_string_value(json_array_get(json_object_get(j_export, "x5c"), 0)), "MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA=="); json_decref(j_export); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_ptr_ne((j_export = r_jwk_export_to_json_t(jwk)), NULL); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kty")), "RSA"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "n")), "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "e")), "AQAB"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "alg")), "RS256"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "kid")), "2011-04-29"); ck_assert_str_eq(json_string_value(json_object_get(j_export, "x5u")), "https://www.example.com/x509"); json_decref(j_export); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_export_to_gnutls_privkey) { jwk_t * jwk; gnutls_privkey_t privkey = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_privkey(jwk), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((privkey = r_jwk_export_to_gnutls_privkey(jwk)), NULL); gnutls_privkey_deinit(privkey); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_privkey(jwk), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_ptr_ne((privkey = r_jwk_export_to_gnutls_privkey(jwk)), NULL); gnutls_privkey_deinit(privkey); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_export_to_gnutls_pubkey) { jwk_t * jwk; gnutls_pubkey_t pubkey = NULL; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7465, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_large", NULL, 0, &callback_x5u_large, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, 0)), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, 0)), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); #if 0 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_secp256k1_str), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, 0)), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); #endif #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, 0)), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, 0)), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_rsa_pub_7465), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE)), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_REMOTE), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_ecdsa_pub_7465), RHN_OK); ck_assert_ptr_ne((pubkey = r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE)), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_REMOTE), NULL); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); y_log_message(Y_LOG_LEVEL_DEBUG, "grut 0"); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); y_log_message(Y_LOG_LEVEL_DEBUG, "grut 1"); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_large_7465), RHN_OK); y_log_message(Y_LOG_LEVEL_DEBUG, "grut 2"); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), NULL); y_log_message(Y_LOG_LEVEL_DEBUG, "grut 3"); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_REMOTE), NULL); y_log_message(Y_LOG_LEVEL_DEBUG, "grut 4"); r_jwk_free(jwk); #endif y_log_message(Y_LOG_LEVEL_DEBUG, "grut 5"); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_export_to_gnutls_crt) { jwk_t * jwk; gnutls_x509_crt_t crt = NULL; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7466, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_large", NULL, 0, &callback_x5u_large, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, 0), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, 0), NULL); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, 0), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, 0), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_ptr_ne((crt = r_jwk_export_to_gnutls_crt(jwk, 0)), NULL); gnutls_x509_crt_deinit(crt); r_jwk_free(jwk); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_rsa_pub_7466), RHN_OK); ck_assert_ptr_ne((crt = r_jwk_export_to_gnutls_crt(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE)), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, R_FLAG_IGNORE_REMOTE), NULL); gnutls_x509_crt_deinit(crt); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_ecdsa_pub_7466), RHN_OK); ck_assert_ptr_ne((crt = r_jwk_export_to_gnutls_crt(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE)), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_crt(jwk, R_FLAG_IGNORE_REMOTE), NULL); gnutls_x509_crt_deinit(crt); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_large_7466), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_REMOTE), NULL); r_jwk_free(jwk); #endif o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_export_to_pem) { jwk_t * jwk; unsigned char data[4096]; size_t data_len = 4096; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7467, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_large", NULL, 0, &callback_x5u_large, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_privkey_ecdsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_pubkey_ecdsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_eddsa_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_privkey_eddsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); #if 0 // Disabled for now ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdh_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_privkey_eddsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); #endif #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_privkey_rsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, 0), RHN_OK); ck_assert_int_eq(o_strncmp(jwk_pubkey_rsa_pem, (const char *)data, data_len), 0); r_jwk_free(jwk); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_rsa_pub_7467), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, R_FLAG_IGNORE_REMOTE), RHN_ERROR); ck_assert_int_eq(o_strncmp(jwk_pubkey_rsa_x5u_export, (const char *)data, data_len), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_ecdsa_pub_7467), RHN_OK); data_len = 4096; ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwk_export_to_pem_der(jwk, R_FORMAT_PEM, data, &data_len, R_FLAG_IGNORE_REMOTE), RHN_ERROR); ck_assert_int_eq(o_strncmp(jwk_pubkey_ecdsa_x5u_export, (const char *)data, data_len), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_large_7467), RHN_OK); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), NULL); ck_assert_ptr_eq(r_jwk_export_to_gnutls_pubkey(jwk, R_FLAG_IGNORE_REMOTE), NULL); r_jwk_free(jwk); #endif o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_export_to_symmetric_key) { jwk_t * jwk; unsigned char key[128] = {0}; size_t key_len = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_export_to_symmetric_key(jwk, key, &key_len), RHN_ERROR_PARAM); ck_assert_int_eq(key_len, 0); ck_assert_int_eq(o_strlen((const char *)key), 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); key_len = 128; ck_assert_int_eq(r_jwk_export_to_symmetric_key(jwk, key, &key_len), RHN_OK); ck_assert_int_eq(o_strncmp(KEY_DECODED, (const char *)key, key_len), 0); r_jwk_free(jwk); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWK export function tests"); tc_core = tcase_create("test_rhonabwy_export"); tcase_add_test(tc_core, test_rhonabwy_export_to_str); tcase_add_test(tc_core, test_rhonabwy_export_to_json); tcase_add_test(tc_core, test_rhonabwy_export_to_gnutls_privkey); tcase_add_test(tc_core, test_rhonabwy_export_to_gnutls_pubkey); tcase_add_test(tc_core, test_rhonabwy_export_to_gnutls_crt); tcase_add_test(tc_core, test_rhonabwy_export_to_pem); tcase_add_test(tc_core, test_rhonabwy_export_to_symmetric_key); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWK export tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwk_import.c000066400000000000000000004253701452472117100167550ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #include #define HTTPS_PORT 7462 #define FULLCHAIN1_FILE "cert/fullchain1.crt" #define FULLCHAIN2_FILE "cert/fullchain2.crt" #define FULLCHAIN_ERROR_FILE "cert/fullchain-error.crt" #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" const unsigned char symmetric_key[] = "secret"; const unsigned char symmetric_key_b64url[] = "c2VjcmV0"; const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_p384_str[] = "{\"crv\":\"P-384\",\"d\":\"IKRyzFYbvLo4JoBMlPPTdIE8mLlcCO03XLh-97aNT3sQ9cT4vb3nSjWCecTUvjW6\","\ "\"kty\":\"EC\",\"x\":\"Nx2Wxf0o6A01m6ymiD7YIfmWkyBrySWzq5N85bMUs_9G8D_l4RRxLj4i7z1_5Rvo\","\ "\"y\":\"c4iG6Gp5vEcoyuGREu40AejY-fkg0K_iYEic1sME-VphV8L94IWJU3EbhA_zEQhb\"}"; const char jwk_pubkey_ecdsa_p384_str[] = "{\"crv\":\"P-384\",\"kty\":\"EC\","\ "\"x\":\"Nx2Wxf0o6A01m6ymiD7YIfmWkyBrySWzq5N85bMUs_9G8D_l4RRxLj4i7z1_5Rvo\","\ "\"y\":\"c4iG6Gp5vEcoyuGREu40AejY-fkg0K_iYEic1sME-VphV8L94IWJU3EbhA_zEQhb\"}"; const char jwk_privkey_ecdsa_p521_str[] = "{\"crv\":\"P-521\",\"d\":\"cz-Y7wdU6n3j6QB5J-KtVg1ozfir1yuRsWBMZ2NvZytGRj0V-41c92HxrsOC-Ia--0sK_ATpnRKlgS5jo286c6o\","\ "\"kty\":\"EC\",\"x\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"y\":\"Aen_lIXMdZhFBSkgPdXGsyNTh6XEDDk74-08nawnxO1YblVM-Rp7FbumjBbCpA7jPxRxKO1h3VJFP93uvqw16RIE\"}"; const char jwk_pubkey_ecdsa_p521_str[] = "{\"crv\":\"P-521\",\"kty\":\"EC\","\ "\"x\":\"Adt3Ill4dNKRMdrDM4GYt-49GFmRcRYLiJveIzg1YkOduLHtoxQ4UQ5GpPZNfoJE3YBQkwoZIUKpG8WHKTHqYtM3\","\ "\"y\":\"Aen_lIXMdZhFBSkgPdXGsyNTh6XEDDk74-08nawnxO1YblVM-Rp7FbumjBbCpA7jPxRxKO1h3VJFP93uvqw16RIE\"}"; const char jwk_pubkey_ecdsa_str_invalid_kty[] = "{\"kty\":\"ECC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_crv[] = "{\"kty\":\"EC\",\"crv\":\"P-256C\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_x[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":42,\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_y[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\",\"y\":42,\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_use[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":42,\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_kid[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":42}"; const char jwk_pubkey_ecdsa_str_missing_x[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_missing_y[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_b64_x[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\";error;\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_invalid_b64_y[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\";error;\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_secp256k1_str[] = "{\"crv\":\"secp256k1\",\"kid\":\"JUvpllMEYUZ2joO59UNui_XYDqxVqiFLLAJ8klWuPBw\",\"kty\":\"EC\"," "\"x\":\"dWCvM4fTdeM0KmloF57zxtBPXTOythHPMm1HCLrdd3A\",\"y\":\"36uMVGM7hnw-N6GnjFcihWE3SkrhMLzzLCdPMXPEXlA\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str_invalid_k[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":42,\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str_invalid_b64_k[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\";error;\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_eddsa_str[] = "{\"kty\":\"OKP\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\","\ "\"d\":\"nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A\"}"; const char jwk_privkey_eddsa_str_invalid_d[] = "{\"kty\":\"OKP\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\","\ "\"d\":42}"; const char jwk_privkey_eddsa_str_invalid_b64_d[] = "{\"kty\":\"OKP\",\"use\":\"sig\",\"crv\":\"Ed25519\",\"x\":\"11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo\","\ "\"d\":\";error;\"}"; const char jwk_privkey_ecdh_str[] = "{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo\"," "\"d\":\"RVqkt2ZmEiUY-OGyag9rXe7vsDm2BQ_XykdxhLv9pd4\"}"; const char jwk_privkey_ecdh_str_invalid_d[] = "{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo\"," "\"d\":42}"; const char jwk_privkey_ecdh_str_invalid_b64_d[] = "{\"kty\":\"OKP\",\"crv\":\"X25519\",\"x\":\"hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo\"," "\"d\":\";error;\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_invalid_n[] = "{\"kty\":\"RSA\",\"n\":42,\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_invalid_e[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_"\ "BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs"\ "8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls"\ "1jF44-csFCur-kEgU8awapJzKnqDKgw\",\"e\":42,\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_invalid_alg[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc"\ "_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSq"\ "zs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw"\ "0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\",\"e\":\"AQAB\",\"alg\":\"RS257\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_invalid_b64_n[] = "{\"kty\":\"RSA\",\"n\":\";error;\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_invalid_b64_e[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\";error;\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_d[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":42,\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_p[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":42,\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_q[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":42,\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_dp[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":42,\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_dq[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":42,\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_qi[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":42,\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_d[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\";error;\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_p[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\";error;\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_q[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\";error;\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_dp[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\";error;\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_dq[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\";error;\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str_invalid_b64_qi[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\";error;\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_key_symmetric[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"GawgguFyGrWKav7AX4VKUg\"}"; const char jwk_key_symmetric_invalid_k[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":42}"; const char jwk_key_symmetric_invalid_b64_k[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\";error;\"}"; const char jwk_pubkey_rsa_x5c_str[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy"\ "2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1qu"\ "GmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqP"\ "pnjL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0\",\"e\":\"AQAB\",\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"]}"; const char jwk_pubkey_rsa_x5c_str_invalid_x5c[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"vrjOfz9Ccdgx5nQudyhdoR17V-IubWMeOZCwX_jj0hgAsz2J_pqYW08PLb"\ "K_PdiVGKPrqzmDIsLI7sA25VEnHU1uCLNwBuUiCO11_-7dYbsr4iJmG0Qu2j8DsVyT1azpJC_NG84Ty5KKthuCaPod7iI7w0LK9orSMhBEwwZDCxTWq4a"\ "YWAchc8t-emd9qOvWtVMDC2BXksRngh6X5bUYLy6AyHKvj-nUy1wgzjYQDwHMTplCoLtU-o-8SNnZ1tmRoGE9uJkBLdh5gFENabWnU5m1ZqZPdwS-qo-m"\ "eMvVfJb6jJVWRpl2SUtCnYG2C32qvbWbjZ_jBPD5eunqsIo1vQ\",\"e\":\"AQAB\",\"x5c\":[42]}"; const char jwk_pubkey_rsa_x5c_str_invalid_x5c_content[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"vrjOfz9Ccdgx5nQudyhdoR17V-IubWMeOZCwX_jj0hgAsz2J_pqYW08PLb"\ "K_PdiVGKPrqzmDIsLI7sA25VEnHU1uCLNwBuUiCO11_-7dYbsr4iJmG0Qu2j8DsVyT1azpJC_NG84Ty5KKthuCaPod7iI7w0LK9orSMhBEwwZDCxTWq4a"\ "YWAchc8t-emd9qOvWtVMDC2BXksRngh6X5bUYLy6AyHKvj-nUy1wgzjYQDwHMTplCoLtU-o-8SNnZ1tmRoGE9uJkBLdh5gFENabWnU5m1ZqZPdwS-qo-m"\ "eMvVfJb6jJVWRpl2SUtCnYG2C32qvbWbjZ_jBPD5eunqsIo1vQ\",\"e\":\"AQAB\",\"x5c\":[\";error;\"]}"; const char jwk_pubkey_rsa_x5c_only[] = "{\"alg\": \"RS256\",\"x5c\":[\"MIIFkjCCBHqgAwIBAgIQRXroN0ZOdRkBAAAAAAPunzANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJVUzEeMBw"\ "GA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMRMwEQYDVQQDEwpHVFMgQ0EgMU8xMB4XDTE4MTAxMDA3MTk0NVoXDTE5MTAwOTA3MTk0NVowbDELMAkGA"\ "1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBMTEMxGzAZBgNVBAMTEmF0dGV"\ "zdC5hbmRyb2lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANjXkz0eK1SE4m+/G5wOo+XGSECrqdn88sCpR7fs14fK0Rh3ZCYZLFHqB"\ "k6AmZVw2K9FG0O9rRPeQDIVRyE30QunS9ugHC4eg9ovvOm+QdZ2p93XhzunQEhUWXCxADIEGJK3S2aAfze99PLS29hLcQuYXHDaC7OZqNnosiOGifs8v1j"\ "i6H/xhltCZe2lJ+7GutzexKpxvpE/tZSfbY905qSlBh9fpj015cjnQFkUsAUwmKVAUueUz4tKcFK4pevNLaxEAl+OkilMtIYDacD5nel4xJiys413hagqW"\ "0Whh5FP39hGk9E/BwQTjazSxGdvX0m6xFYhh/2VMyZjT4KzPJECAwEAAaOCAlgwggJUMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATA"\ "MBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQqBQwGWoJBa1oTKqupo4W6xT6j2DAfBgNVHSMEGDAWgBSY0fhuEOvPm+xgnxiQG6DrfQn9KzBkBggrBgEFBQcBA"\ "QRYMFYwJwYIKwYBBQUHMAGGG2h0dHA6Ly9vY3NwLnBraS5nb29nL2d0czFvMTArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nL2dzcjIvR1RTMU8xLmN"\ "ydDAdBgNVHREEFjAUghJhdHRlc3QuYW5kcm9pZC5jb20wIQYDVR0gBBowGDAIBgZngQwBAgIwDAYKKwYBBAHWeQIFAzAvBgNVHR8EKDAmMCSgIqAghh5od"\ "HRwOi8vY3JsLnBraS5nb29nL0dUUzFPMS5jcmwwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdwCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAA"\ "AAWZdD3PLAAAEAwBIMEYCIQCSZCWeLJvsiVW6Cg+gj/9wYTJRzu4Hiqe4eY4c/myzjgIhALSbi/Thzczqtij3dk3vbLcIW3Ll2B0o75GQdhMigbBgAHUAV"\ "hQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFmXQ9z5AAABAMARjBEAiBcCwA9j7NTGXP278z4hr/uCHiAFLyoCq2K0+yLRwJUbgIgf8gHjvp"\ "w2mB1ESjq2Of3A0AEAwCknCaEKFUyZ7f/QtIwDQYJKoZIhvcNAQELBQADggEBAI9nTfRKIWgtlWl3wBL55ETV6kazsphW1yAc5Dum6XO41kZzwJ61wJmdR"\ "RT/UsCIy1KEt2c0EjglnJCF2eawcEWlLQY2XPLyFjkWQNbShB1i4W2NRGzPht3m1b49hbstuXM6tX5CyEHnTh8Bom4/WlFihzhgn81Dldogz/K2UwM6S6C"\ "B/SExkiVfv+zbJ0rjvg94AldjUfUwkI9VNMjEP5e8ydB3oLl6glpCeF5dgfSX4U9x35oj/IId3UE/dPpb/qgGvskfdeztmUte/KSmriwcgUWWeXfTbI3zs"\ "ikwZbkpmRYKmjPmhv4rlizGCGt8Pn8pq8M2KDf/P3kVot3e18Q=\",\"MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMS"\ "AwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAw"\ "NDJaFw0yMTEyMTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3QgU2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwgg"\ "EiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnvUA0Qk28FgICfKqC9EksC4T2fWBYk/jCf"\ "C3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRrmBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++AcxGNhr59qM/9il71I2dN8FG"\ "fcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmKFsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7XrJfoucBZEqFJ"\ "JSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEw"\ "EB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8GA1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEB"\ "BCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3"\ "NyMi5jcmwwPwYDVR0gBDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOC"\ "AQEAGoA+Nnn78y6pRjd9XlQWNa7HTgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoNFvhsO9tvBCOIazpswWC9aJ9xju"\ "4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrzmqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wWIRdAvKLWZu/axBVb"\ "zYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZUSpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==\"],\""\ "kty\":\"RSA\"}"; const char jwk_pubkey_rsa_x5c_only_invalid_type[] = "{\"alg\": \"ES256\",\"x5c\":[\"MIIFkjCCBHqgAwIBAgIQRXroN0ZOdRkBAAAAAAPunzANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJVUzEeMBw"\ "GA1UEChMVR29vZ2xlIFRydXN0IFNlcnZpY2VzMRMwEQYDVQQDEwpHVFMgQ0EgMU8xMB4XDTE4MTAxMDA3MTk0NVoXDTE5MTAwOTA3MTk0NVowbDELMAkGA"\ "1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBMTEMxGzAZBgNVBAMTEmF0dGV"\ "zdC5hbmRyb2lkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANjXkz0eK1SE4m+/G5wOo+XGSECrqdn88sCpR7fs14fK0Rh3ZCYZLFHqB"\ "k6AmZVw2K9FG0O9rRPeQDIVRyE30QunS9ugHC4eg9ovvOm+QdZ2p93XhzunQEhUWXCxADIEGJK3S2aAfze99PLS29hLcQuYXHDaC7OZqNnosiOGifs8v1j"\ "i6H/xhltCZe2lJ+7GutzexKpxvpE/tZSfbY905qSlBh9fpj015cjnQFkUsAUwmKVAUueUz4tKcFK4pevNLaxEAl+OkilMtIYDacD5nel4xJiys413hagqW"\ "0Whh5FP39hGk9E/BwQTjazSxGdvX0m6xFYhh/2VMyZjT4KzPJECAwEAAaOCAlgwggJUMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATA"\ "MBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQqBQwGWoJBa1oTKqupo4W6xT6j2DAfBgNVHSMEGDAWgBSY0fhuEOvPm+xgnxiQG6DrfQn9KzBkBggrBgEFBQcBA"\ "QRYMFYwJwYIKwYBBQUHMAGGG2h0dHA6Ly9vY3NwLnBraS5nb29nL2d0czFvMTArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nL2dzcjIvR1RTMU8xLmN"\ "ydDAdBgNVHREEFjAUghJhdHRlc3QuYW5kcm9pZC5jb20wIQYDVR0gBBowGDAIBgZngQwBAgIwDAYKKwYBBAHWeQIFAzAvBgNVHR8EKDAmMCSgIqAghh5od"\ "HRwOi8vY3JsLnBraS5nb29nL0dUUzFPMS5jcmwwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdwCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAA"\ "AAWZdD3PLAAAEAwBIMEYCIQCSZCWeLJvsiVW6Cg+gj/9wYTJRzu4Hiqe4eY4c/myzjgIhALSbi/Thzczqtij3dk3vbLcIW3Ll2B0o75GQdhMigbBgAHUAV"\ "hQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFmXQ9z5AAABAMARjBEAiBcCwA9j7NTGXP278z4hr/uCHiAFLyoCq2K0+yLRwJUbgIgf8gHjvp"\ "w2mB1ESjq2Of3A0AEAwCknCaEKFUyZ7f/QtIwDQYJKoZIhvcNAQELBQADggEBAI9nTfRKIWgtlWl3wBL55ETV6kazsphW1yAc5Dum6XO41kZzwJ61wJmdR"\ "RT/UsCIy1KEt2c0EjglnJCF2eawcEWlLQY2XPLyFjkWQNbShB1i4W2NRGzPht3m1b49hbstuXM6tX5CyEHnTh8Bom4/WlFihzhgn81Dldogz/K2UwM6S6C"\ "B/SExkiVfv+zbJ0rjvg94AldjUfUwkI9VNMjEP5e8ydB3oLl6glpCeF5dgfSX4U9x35oj/IId3UE/dPpb/qgGvskfdeztmUte/KSmriwcgUWWeXfTbI3zs"\ "ikwZbkpmRYKmjPmhv4rlizGCGt8Pn8pq8M2KDf/P3kVot3e18Q=\",\"MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMS"\ "AwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAw"\ "NDJaFw0yMTEyMTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3QgU2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwgg"\ "EiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnvUA0Qk28FgICfKqC9EksC4T2fWBYk/jCf"\ "C3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRrmBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++AcxGNhr59qM/9il71I2dN8FG"\ "fcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmKFsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7XrJfoucBZEqFJ"\ "JSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEw"\ "EB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8GA1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEB"\ "BCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3"\ "NyMi5jcmwwPwYDVR0gBDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOC"\ "AQEAGoA+Nnn78y6pRjd9XlQWNa7HTgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoNFvhsO9tvBCOIazpswWC9aJ9xju"\ "4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrzmqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wWIRdAvKLWZu/axBVb"\ "zYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZUSpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg==\"],\""\ "kty\":\"EC\"}"; const char jwk_pubkey_rsa_x5u_str[] = "{\"kty\":\"RSA\",\"n\":\"sUWjL3wK1B_dQbXbhSXaodF0gXMNlZg3ZecjZIJOKgXGDVOnV0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul9kyzpPBr53"\ "ELHMmAeI_I1rnF4pgIwfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHhtST9V874mMehsSUG4xM2qiBvvbWwX0KCyKk6BY_CdyljUjAPUShcVysKUTyfefew"\ "38KUVTVpk2vWLlN-a41iC_gxGvLtH142LDiDx_s-Kh37f4paD2zsEw5McF81eiKTAfrraIC1Gj2BxyEj6n2EjqyI-NFRsSUmqfPoFgiMzlEWj4P8AwvfE9"\ "jbjXz_E0GOISiXt4L-06U7rLoGHFri5oVI6KUkLAOwwwTri-ikeQFx68IKvhytBiX1O-XHh51JZyyC-fcKKN-_ATgGKIiR63M5UWYxO2JkVkPvpzORKJUi"\ "vePFQbkEcxYZb9VqoVZ04sfpfGb3h2douzBrKbkDP_Jf-O0JPKDTltrUJOpZbYhV\",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-"\ "29\",\"x5u\":\"https://localhost:7464/x5u_rsa_crt\"}"; const char jwk_pubkey_rsa_x5u_large[] = "{\"kty\":\"RSA\",\"n\":\"sUWjL3wK1B_dQbXbhSXaodF0gXMNlZg3ZecjZIJOKgXGDVOnV0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul9kyzpPBr53"\ "ELHMmAeI_I1rnF4pgIwfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHhtST9V874mMehsSUG4xM2qiBvvbWwX0KCyKk6BY_CdyljUjAPUShcVysKUTyfefew"\ "38KUVTVpk2vWLlN-a41iC_gxGvLtH142LDiDx_s-Kh37f4paD2zsEw5McF81eiKTAfrraIC1Gj2BxyEj6n2EjqyI-NFRsSUmqfPoFgiMzlEWj4P8AwvfE9"\ "jbjXz_E0GOISiXt4L-06U7rLoGHFri5oVI6KUkLAOwwwTri-ikeQFx68IKvhytBiX1O-XHh51JZyyC-fcKKN-_ATgGKIiR63M5UWYxO2JkVkPvpzORKJUi"\ "vePFQbkEcxYZb9VqoVZ04sfpfGb3h2douzBrKbkDP_Jf-O0JPKDTltrUJOpZbYhV\",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-"\ "29\",\"x5u\":\"https://localhost:7464/x5u_large\"}"; const char jwk_pubkey_rsa_x5u_only_rsa_pub[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7464/x5u_rsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_ecdsa_pub[] = "{\"kty\":\"EC\",\"alg\":\"ES256\",\"x5u\":\"https://localhost:7464/x5u_ecdsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_eddsa_pub[] = "{\"kty\":\"OKP\",\"alg\":\"ES256\",\"x5u\":\"https://localhost:7464/x5u_eddsa_crt\"}"; const char jwk_pubkey_rsa_x5u_only_ecdsa_pub_invalid_type[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7464/x5u_ecdsa_crt\"}"; const char jwk_pubkey_rsa_x5u_str_invalid_x5u[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWK"\ "RXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZ"\ "zu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqD"\ "Kgw\",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\",\"x5u\":42}"; const char jwk_pubkey_rsa_x5u_str_invalid_x5u_protocol[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\",\"x5u\":\"http://www.example.com/x509\"}"; const char jwk_invalid_json[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"GawgguFyGrWKav7AX4VKUg\""; const char jwk_invalid_json_container[] = "[{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"GawgguFyGrWKav7AX4VKUg\"}]"; const char jwk_privkey_rsa_x5c_x5u_x5t_x5ts256_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\","\ "\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"],\"x5u\":\"https://localhost:7464/x5u_rsa_crt\",\"x5t\":\"abcd\",\"x5t#S256\":\"abcdS256\"}"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; const unsigned char rsa_2048_pub_der[] = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\ uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\ iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\ ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\ 6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\ K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\ BwIDAQAB"; const unsigned char rsa_2048_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\n" "iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\n" "lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\n" "Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\n" "TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\n" "45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\n" "2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\n" "n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\n" "wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\n" "z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\n" "3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\n" "UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\n" "DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\n" "DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\n" "m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\n" "cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\n" "1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\n" "I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\n" "INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\n" "vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\n" "Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\n" "TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\n" "+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\n" "mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\n" "LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\n" "tEOtzsP5GMDYVlEp1jYSjzQ=\n" "-----END PRIVATE KEY-----\n"; const unsigned char rsa_2048_priv_der[] = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\ iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\ lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\ Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\ TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\ 45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\ 2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\ n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\ wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\ z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\ 3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\ UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\ DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\ DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\ m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\ cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\ 1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\ I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\ INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\ vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\ Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\ TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\ +wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\ mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\ LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\ tEOtzsP5GMDYVlEp1jYSjzQ="; const unsigned char ecdsa_521_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA/axE26pXWXesAjcTP/2Tfe4EcF4A\n" "3LuqgpIFzrftiztViq0+5deUvfcxuPIFk+ANVinlAOzgZWpFS0kheI7KJAYA3fOH\n" "n5ZTU08AAjau0CoZe9GSPUC4cnSy1nqetiKBW0YpBvhaY5FXnngvfHUHdmkFSVLC\n" "S6N+LXoi/dm0Fbo6snE=\n" "-----END PUBLIC KEY-----\n"; const unsigned char ecdsa_521_pub_der[] = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA/axE26pXWXesAjcTP/2Tfe4EcF4A\ 3LuqgpIFzrftiztViq0+5deUvfcxuPIFk+ANVinlAOzgZWpFS0kheI7KJAYA3fOH\ n5ZTU08AAjau0CoZe9GSPUC4cnSy1nqetiKBW0YpBvhaY5FXnngvfHUHdmkFSVLC\ S6N+LXoi/dm0Fbo6snE="; const unsigned char ecdsa_521_priv[] = "-----BEGIN EC PRIVATE KEY-----\n" "MIHcAgEBBEIAp6rxb2PoAISjCCTxpTQOxv5arJ/N6Xibr0eyOAnlWcVk34m1W532\n" "3/6TcPGTtFQgEX9TWjNcp9W8HIuIyRdLnsKgBwYFK4EEACOhgYkDgYYABAD9rETb\n" "qldZd6wCNxM//ZN97gRwXgDcu6qCkgXOt+2LO1WKrT7l15S99zG48gWT4A1WKeUA\n" "7OBlakVLSSF4jsokBgDd84efllNTTwACNq7QKhl70ZI9QLhydLLWep62IoFbRikG\n" "+FpjkVeeeC98dQd2aQVJUsJLo34teiL92bQVujqycQ==\n" "-----END EC PRIVATE KEY-----\n"; const unsigned char ecdsa_521_priv_der[] = "MIHcAgEBBEIAp6rxb2PoAISjCCTxpTQOxv5arJ/N6Xibr0eyOAnlWcVk34m1W532\ 3/6TcPGTtFQgEX9TWjNcp9W8HIuIyRdLnsKgBwYFK4EEACOhgYkDgYYABAD9rETb\ qldZd6wCNxM//ZN97gRwXgDcu6qCkgXOt+2LO1WKrT7l15S99zG48gWT4A1WKeUA\ 7OBlakVLSSF4jsokBgDd84efllNTTwACNq7QKhl70ZI9QLhydLLWep62IoFbRikG\ +FpjkVeeeC98dQd2aQVJUsJLo34teiL92bQVujqycQ=="; const unsigned char ed25519_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MC4CAQAwBQYDK2VwBCIEIGHd6sDtpeBmGNOiJ/KG8Xa85bywgofA0jAZH/1f3Xnj\n" "-----END PRIVATE KEY-----"; const unsigned char ed25519_priv_der[] = "MC4CAQAwBQYDK2VwBCIEIGHd6sDtpeBmGNOiJ/KG8Xa85bywgofA0jAZH/1f3Xnj"; const unsigned char ed448_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MEcCAQAwBQYDK2VxBDsEOTpVxVqZcGq1PfqUS+Tct02m1uSsb30rIiBuartRwFqo\n" "9NeuVKd9K0YVM9biq3X7WW1kDOdPK0nBog==\n" "-----END PRIVATE KEY-----"; const unsigned char ed448_priv_der[] = "MEcCAQAwBQYDK2VxBDsEOTpVxVqZcGq1PfqUS+Tct02m1uSsb30rIiBuartRwFqo" "9NeuVKd9K0YVM9biq3X7WW1kDOdPK0nBog=="; const unsigned char x25519_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MC4CAQAwBQYDK2VuBCIEIHgz5JhbrOOKkJIqxQnnSpKGC1ncvqPBwCGIFJtsVeVT\n" "-----END PRIVATE KEY-----"; const unsigned char x25519_priv_der[] = "MC4CAQAwBQYDK2VuBCIEIHgz5JhbrOOKkJIqxQnnSpKGC1ncvqPBwCGIFJtsVeVT"; const unsigned char x448_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MEYCAQAwBQYDK2VvBDoEOKBu7PIoYBVNeVQ8erUnN7B6M+Jtmvdjl/GMmoxZ00DA\n" "OicTWxiiQZCn0bzut2UqtQ6ay/oN0y75\n" "-----END PRIVATE KEY-----"; const unsigned char x448_priv_der[] = "MEYCAQAwBQYDK2VvBDoEOKBu7PIoYBVNeVQ8erUnN7B6M+Jtmvdjl/GMmoxZ00DA" "OicTWxiiQZCn0bzut2UqtQ6ay/oN0y75"; const unsigned char x509_cert[] = "-----BEGIN CERTIFICATE-----\n" "MIIBejCCASGgAwIBAgIUUmwvBcKwJSWZMLC9xtUYQhh/YicwCgYIKoZIzj0EAwIw\n" "EzERMA8GA1UEAwwIZ2xld2x3eWQwHhcNMTkwNjEyMTY0MjExWhcNMjkwNjA5MTY0\n" "MjExWjATMREwDwYDVQQDDAhnbGV3bHd5ZDBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" "A0IABKP9Eu2Rzt15pKqriLiniryG9zsabCq+aNneB+mmIDwRkjaqpKeGwztLEHBG\n" "TrHh9poToHkaxUuFE/wVD+9GscGjUzBRMB0GA1UdDgQWBBQQv5dX9gxGFfEDD2Zu\n" "jZQT3FTitDAfBgNVHSMEGDAWgBQQv5dX9gxGFfEDD2ZujZQT3FTitDAPBgNVHRMB\n" "Af8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIBqkd3kqcKZ/gEsnAVi5sQR3gB04\n" "U8JNjzPwv//HmV/FAiBT45X52j1G6QGPg82twWR7CZiHbJPe26drWkkoDeT/QQ==\n" "-----END CERTIFICATE-----\n"; const unsigned char x509_cert_der[] = "MIIBejCCASGgAwIBAgIUUmwvBcKwJSWZMLC9xtUYQhh/YicwCgYIKoZIzj0EAwIw\ EzERMA8GA1UEAwwIZ2xld2x3eWQwHhcNMTkwNjEyMTY0MjExWhcNMjkwNjA5MTY0\ MjExWjATMREwDwYDVQQDDAhnbGV3bHd5ZDBZMBMGByqGSM49AgEGCCqGSM49AwEH\ A0IABKP9Eu2Rzt15pKqriLiniryG9zsabCq+aNneB+mmIDwRkjaqpKeGwztLEHBG\ TrHh9poToHkaxUuFE/wVD+9GscGjUzBRMB0GA1UdDgQWBBQQv5dX9gxGFfEDD2Zu\ jZQT3FTitDAfBgNVHSMEGDAWgBQQv5dX9gxGFfEDD2ZujZQT3FTitDAPBgNVHRMB\ Af8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIBqkd3kqcKZ/gEsnAVi5sQR3gB04\ U8JNjzPwv//HmV/FAiBT45X52j1G6QGPg82twWR7CZiHbJPe26drWkkoDeT/QQ=="; const unsigned char error_pem[] = "-----BEGIN ERROR FROM OUTER SPACE-----"; const unsigned char rsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIEWTCCAsGgAwIBAgIUJyAFwqkMTppNiyU8gFOK4WUC1GgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0xOTEyMDYxMzU1MzlaFw0yMDExMjAxMzU1MzlaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MIIBojANBgkqhkiG9w0BAQEFAAOC\n" "AY8AMIIBigKCAYEAsUWjL3wK1B/dQbXbhSXaodF0gXMNlZg3ZecjZIJOKgXGDVOn\n" "V0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul9kyzpPBr53ELHMmAeI/I1rnF4pgI\n" "wfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHhtST9V874mMehsSUG4xM2qiBvvbWw\n" "X0KCyKk6BY/CdyljUjAPUShcVysKUTyfefew38KUVTVpk2vWLlN+a41iC/gxGvLt\n" "H142LDiDx/s+Kh37f4paD2zsEw5McF81eiKTAfrraIC1Gj2BxyEj6n2EjqyI+NFR\n" "sSUmqfPoFgiMzlEWj4P8AwvfE9jbjXz/E0GOISiXt4L+06U7rLoGHFri5oVI6KUk\n" "LAOwwwTri+ikeQFx68IKvhytBiX1O+XHh51JZyyC+fcKKN+/ATgGKIiR63M5UWYx\n" "O2JkVkPvpzORKJUivePFQbkEcxYZb9VqoVZ04sfpfGb3h2douzBrKbkDP/Jf+O0J\n" "PKDTltrUJOpZbYhVAgMBAAGjdjB0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYI\n" "KwYBBQUHAwIwDwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUiZGaRSyAyraAdeo5\n" "wJc+0Ks7IOcwHwYDVR0jBBgwFoAU0marYk/GnTVDeDbie2BY15qCu0QwDQYJKoZI\n" "hvcNAQELBQADggGBAGINVR+lskHnxkYvPkgCQG+nGqovI28W6rtx8a5xM/6rtsVs\n" "5jCu1nnJd32YNjDsySxsbkhXjW0WjGR7cEsnmcOITeP4kLLVzh1vm6sZa/9vX1fh\n" "M5pTUTYTHYozl6TA85CtBd7oC/AB2Gwh5q1kJ3wmGwmCY8mqPftP+plyFTSbCwAH\n" "BZSfCgsMpffILDzPgViU54BehfpfljZcmGJnnGKEnTRvUr84/NlmKEdhw9rKyod5\n" "KKieGneVzpPeiyXrzUEJuGkmLtVLpvNdDdB5+6rN0hK+bFyB3NA+gASIiekuM7Q+\n" "4RgroWwTF7fq1XUhX3aexOI2eTx0B2bBpD28TcYvqo6Y+aBKHVbo8gnbMr5IoIkI\n" "rYz8CXrbbZFRilsHRQgzyEmTq/Wp0GVt/zakMF7suA8nl/AQcKDOWGBnEFc+okAe\n" "K0P/4R4UnQSPU8SfsFBGxm4PXN4BZktZ10LC/xKMJBkdSD0vTLce9Sx7xR4PUIaN\n" "n2x0D4zZG7px73kB0Q==\n" "-----END CERTIFICATE-----"; const unsigned char ecdsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIDNjCCAZ6gAwIBAgIUDzxOEj+8WUrLa1M97arwkEo5gEwwDQYJKoZIhvcNAQEL\n" "BQAwMjEbMBkGA1UEAwwSZ2xld2x3eWRfcGFja2VkX2NhMRMwEQYDVQQKEwpiYWJl\n" "bG91ZXN0MB4XDTE5MTIwNjEzNTYxM1oXDTIwMTEyMDEzNTYxM1owYDEYMBYGA1UE\n" "AwwPZ2xld2x3eWRfcGFja2VkMSIwIAYDVQQLExlBdXRoZW50aWNhdG9yIEF0dGVz\n" "dGF0aW9uMRMwEQYDVQQKEwpiYWJlbG91ZXN0MQswCQYDVQQGEwJDQTBZMBMGByqG\n" "SM49AgEGCCqGSM49AwEHA0IABOjeoVGraskp+jax8TTOXy92o6PGGN2Tl3XshqN/\n" "XZnfkyxxLxKvJ0igfQ4Qy4/9w8PGjVilnY4zR3y25VJ7KLejYTBfMAwGA1UdEwEB\n" "/wQCMAAwDwYDVR0PAQH/BAUDAweAADAdBgNVHQ4EFgQU34GPDg2bLIneLKIfjYjU\n" "NuiU170wHwYDVR0jBBgwFoAUlOaykWFTL+EV/0PHksB2Dh1k1KAwDQYJKoZIhvcN\n" "AQELBQADggGBAFHNuUQUkZaunXfV3qSemhlyHH1hnt6YXJLIl2IKugg/mg8hga2C\n" "dBN7MMcVYpXtNI8AKfSIZRu3v16OMIajCIh7PYGa5asbJZgtOkbvfc58eaWhzl8U\n" "B0j89aGlntZs3WWINYgqfzBS6Pw3SJ5iVTpS+xH2JSWxZYX3uvEDkVkw1VjmyyN3\n" "ZX0tkFTKQB3GNFZwesxoRKizsu8r+tCIqgfqRTG7FIOa/UB3MXVClA//+TCnW2RI\n" "48JzjY/YhO54pWVsblHAQwMOmuHlJrnfLFPvBqFx5mi8Z5jHfZipsNksIteKFdtG\n" "3FvjQYIj2wJM9k7XHrQ3szxwvq9Ss2cyCBPArrKVpBTibypIkON9R2Peocr3HkUx\n" "YYhu3pNumaSdGzL0r7A2iGIXy9orIAQ8f1i7iaYDBWs/PkJ340iHRZtSuez8F+GN\n" "NUV15utv9AMvahkCI5ZS71TAv4AFjsZpsvYuCvpUUPdZpC+r9lk8H1wa4VA+mujL\n" "2Yxh1fFV7ONNjA==\n" "-----END CERTIFICATE-----"; const unsigned char eddsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIDLDCCAZSgAwIBAgIUTuClu4hNHMPpKcw6+rjDqVXaQVkwDQYJKoZIhvcNAQEL\n" "BQAwMjEbMBkGA1UEAwwSZ2xld2x3eWRfcGFja2VkX2NhMRMwEQYDVQQKEwpiYWJl\n" "bG91ZXN0MB4XDTIxMDgzMDE0MzY1OVoXDTIyMDgxNTE0MzY1OVowYDEYMBYGA1UE\n" "AwwPZ2xld2x3eWRfcGFja2VkMSIwIAYDVQQLExlBdXRoZW50aWNhdG9yIEF0dGVz\n" "dGF0aW9uMRMwEQYDVQQKEwpiYWJlbG91ZXN0MQswCQYDVQQGEwJDQTAqMAUGAytl\n" "cAMhAIouRueZYs1tzatbfdECcJwHwun+WXzH3CBy8BJxJYcLo4GFMIGCMCEGCysG\n" "AQQBguUcAQEEBBIEEEJDREVGR0hJUFFSU1RVVlcwDAYDVR0TAQH/BAIwADAPBgNV\n" "HQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBS6GVmW2tFiBlvcLopMuEv2UFlTRTAfBgNV\n" "HSMEGDAWgBRYdd7pkDm7ZUQq0dg+usf8qHk4DjANBgkqhkiG9w0BAQsFAAOCAYEA\n" "K7L+G+skxijb+9onGRpnsJ98JTBiPMoyvvTzmkw54JiYufG3fkbumM+TRohyydEQ\n" "4bZT/yiO8KJz3Y3D7QKKDxZTPm6/lGlrFVzlJ18CNvRoypvws1VOik6iroJBvCQO\n" "YpiuKlcK+g7kQxGkk5i/2roohzxJHFUqJ6vKGRsxg3GySBSCS+BjLPHQckUnQhdP\n" "WcNthoYnqNpSwyAIWgQ6D/Hus7nUI3EVzDmXPwWYRhxtuBVMhw9nWi7xO89kQGjl\n" "zcCFzVI23ktwTDBt1XNHlxwuqnWKDBdPFd+UJvplE9tcr2I5IoLf+wtUx9/8zPcS\n" "cYWbe1bTykoZXGFJJaVU+58sT9CseICfScCwwMgd2kZ7zFtgceOqaOuIgAoD0ub2\n" "2YbXZ/M+B1Z1TDQ2qF+KdHBQvrp8bbf0Y3CMgPPzJmABuzVSOxazqBSgMSufrlzA\n" "s0nRjPr3UZRaPv5RDpGk8eqGU7szhTrMpr0/lX30YNuXndPWfD/axRvvAH0EtvhI\n" "-----END CERTIFICATE-----"; const char x5u_fullchain1_crt[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_fullchain1\"}"; const char x5u_fullchain2_crt[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_fullchain2\"}"; const char x5u_fullchain_error_crt[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_fullchain_error\"}"; const char x5u_fullchain1_trucated_crt[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\",\"x5u\":\"https://localhost:7465/x5u_fullchain1_trucated\"}"; static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_x5u_rsa_priv (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)rsa_2048_priv); return U_CALLBACK_CONTINUE; } int callback_x5u_rsa_pubkey (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)rsa_2048_pub); return U_CALLBACK_CONTINUE; } int callback_x5u_error (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, "ZXJyb3I="); return U_CALLBACK_CONTINUE; } int callback_x5u_rsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)rsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)ecdsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_large (const struct _u_request * request, struct _u_response * response, void * user_data) { char * large_body = o_malloc((6*1024*1024)); memset(large_body, ' ', (6*1024*1024)); o_strcpy(large_body, (const char *)ecdsa_crt); ulfius_set_binary_body_response(response, 200, (const char *)large_body, (6*1024*1024)); o_free(large_body); return U_CALLBACK_CONTINUE; } int callback_x5u_eddsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)eddsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_fullchain1 (const struct _u_request * request, struct _u_response * response, void * user_data) { char * cert_file = get_file_content(FULLCHAIN1_FILE); ulfius_set_string_body_response(response, 200, cert_file); o_free(cert_file); return U_CALLBACK_CONTINUE; } int callback_x5u_fullchain2 (const struct _u_request * request, struct _u_response * response, void * user_data) { char * cert_file = get_file_content(FULLCHAIN2_FILE); ulfius_set_string_body_response(response, 200, cert_file); o_free(cert_file); return U_CALLBACK_CONTINUE; } int callback_x5u_fullchain_error (const struct _u_request * request, struct _u_response * response, void * user_data) { char * cert_file = get_file_content(FULLCHAIN_ERROR_FILE); ulfius_set_string_body_response(response, 200, cert_file); o_free(cert_file); return U_CALLBACK_CONTINUE; } int callback_x5u_fullchain1_trucated (const struct _u_request * request, struct _u_response * response, void * user_data) { char * cert_file = get_file_content(FULLCHAIN1_FILE); cert_file[o_strlen(cert_file)-30] = '\0'; ulfius_set_string_body_response(response, 200, cert_file); o_free(cert_file); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_import_from_json_str) { jwk_t * jwk; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7464, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_large", NULL, 0, &callback_x5u_large, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_p384_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_p521_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_secp256k1_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_kty), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_crv), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_x), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_y), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_use), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_kid), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_missing_x), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_missing_y), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_b64_x), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str_invalid_b64_y), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_p384_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_p521_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str_invalid_k), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str_invalid_b64_k), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_eddsa_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_eddsa_str_invalid_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_eddsa_str_invalid_b64_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdh_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdh_str_invalid_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdh_str_invalid_b64_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str_invalid_n), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str_invalid_b64_n), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str_invalid_e), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str_invalid_b64_e), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str_invalid_alg), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_d), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_p), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_p), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_q), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_q), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_dp), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_dp), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_dq), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_dq), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_qi), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str_invalid_b64_qi), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_invalid_k), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_invalid_b64_k), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_only), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str_invalid_x5c), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str_invalid_x5c_content), RHN_ERROR_PARAM); r_jwk_free(jwk); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str_invalid_x5u), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str_invalid_x5u_protocol), RHN_ERROR_PARAM); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_invalid_json), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_invalid_json_container), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "error"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "42"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "null"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "false"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, ""), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "{\"error"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "{\"error\":\"error\""), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "{\"error\":\"error\"}"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "{\"error\":42}"), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, "[\"error\",\"error\"]"), RHN_ERROR_PARAM); r_jwk_free(jwk); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_rsa_pub), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_symmetric_key(NULL, symmetric_key, o_strlen((const char *)symmetric_key)), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_symmetric_key(jwk, NULL, o_strlen((const char *)symmetric_key)), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_symmetric_key(jwk, symmetric_key, 0), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_symmetric_key(jwk, symmetric_key, o_strlen((const char *)symmetric_key)), RHN_OK); ck_assert_str_eq("oct", r_jwk_get_property_str(jwk, "kty")); ck_assert_str_eq((const char *)symmetric_key_b64url, r_jwk_get_property_str(jwk, "k")); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_password(NULL, (const char *)symmetric_key), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_password(jwk, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_password(jwk, ""), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_password(jwk, (const char *)symmetric_key), RHN_OK); ck_assert_str_eq("oct", r_jwk_get_property_str(jwk, "kty")); ck_assert_str_eq((const char *)symmetric_key_b64url, r_jwk_get_property_str(jwk, "k")); r_jwk_free(jwk); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_import_from_json_t) { jwk_t * jwk; json_t * j_input; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_kty, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_crv, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_x, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_y, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_use, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_kid, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_ecdsa_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_ecdsa_str_invalid_k, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_eddsa_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_eddsa_str_invalid_d, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_ecdh_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_ecdh_str_invalid_d, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_str_invalid_n, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_str_invalid_e, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_str_invalid_alg, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_d, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_p, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_q, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_dp, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_dq, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_privkey_rsa_str_invalid_qi, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_key_symmetric, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_key_symmetric_invalid_k, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_x5c_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_x5c_str_invalid_x5c, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_x5u_str, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_OK); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_pubkey_rsa_x5u_str_invalid_x5u, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_loads(jwk_invalid_json_container, JSON_DECODE_ANY, NULL), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_pack("[o]", json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL)), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_ne(j_input = json_pack("{so}", "key", json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL)), NULL); ck_assert_int_eq(r_jwk_import_from_json_t(jwk, j_input), RHN_ERROR_PARAM); json_decref(j_input); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_import_from_pem) { jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PUBKEY, R_FORMAT_PEM, rsa_2048_pub, o_strlen((const char *)rsa_2048_pub)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, rsa_2048_pub, o_strlen((const char *)rsa_2048_pub)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_RSA|R_KEY_TYPE_PUBLIC)); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PUBKEY, R_FORMAT_PEM, ecdsa_521_pub, o_strlen((const char *)ecdsa_521_pub)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, ecdsa_521_pub, o_strlen((const char *)ecdsa_521_pub)), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_RSA|R_KEY_TYPE_PUBLIC)); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, x509_cert, o_strlen((const char *)x509_cert)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, x509_cert, o_strlen((const char *)x509_cert)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_RSA|R_KEY_TYPE_PUBLIC)); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, rsa_2048_priv, o_strlen((const char *)rsa_2048_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, rsa_2048_priv, o_strlen((const char *)rsa_2048_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_RSA|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, ecdsa_521_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, ecdsa_521_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_EC|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, error_pem, o_strlen((const char *)error_pem)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_ERROR_PARAM); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, error_pem, o_strlen((const char *)error_pem)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_ERROR_PARAM); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, ed25519_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, ed25519_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_EDDSA|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x03060e ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, ed448_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, ed448_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_EDDSA|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); #endif #if 0 // Disabled for now ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, x25519_priv, o_strlen((const char *)x25519_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, x25519_priv, o_strlen((const char *)x25519_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_EDDSA|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, x448_priv, o_strlen((const char *)x448_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_UNSPECIFIED, R_FORMAT_PEM, x448_priv, o_strlen((const char *)x448_priv)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_ne(0, r_jwk_key_type(jwk, NULL, 0) & (R_KEY_TYPE_EDDSA|R_KEY_TYPE_PRIVATE)); r_jwk_free(jwk); #endif #endif } END_TEST START_TEST(test_rhonabwy_import_from_der) { jwk_t * jwk; unsigned char der_decoded[4096]; size_t der_dec_len = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(rsa_2048_pub_der, o_strlen((const char *)rsa_2048_pub_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PUBKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(ecdsa_521_pub_der, o_strlen((const char *)ecdsa_521_pub_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PUBKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(x509_cert_der, o_strlen((const char *)x509_cert_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(rsa_2048_priv_der, o_strlen((const char *)rsa_2048_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(ecdsa_521_priv_der, o_strlen((const char *)ecdsa_521_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #endif #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(ed25519_priv_der, o_strlen((const char *)ed25519_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x03060e ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(ed448_priv_der, o_strlen((const char *)ed448_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #endif #if 0 // Disabled for now ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(x25519_priv_der, o_strlen((const char *)x25519_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(o_base64_decode(x448_priv_der, o_strlen((const char *)x448_priv_der), der_decoded, &der_dec_len), 1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_PRIVKEY, R_FORMAT_DER, der_decoded, der_dec_len), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); #endif #endif } END_TEST START_TEST(test_rhonabwy_import_from_gnutls) { gnutls_privkey_t privkey; gnutls_x509_privkey_t x509_key; gnutls_pubkey_t pubkey; gnutls_x509_crt_t crt; gnutls_datum_t data; jwk_t * jwk; gnutls_privkey_init(&privkey); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_init(&x509_key)); data.data = (unsigned char *)rsa_2048_priv; data.size = sizeof(rsa_2048_priv); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_import(x509_key, &data, GNUTLS_X509_FMT_PEM)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_privkey_import_x509(privkey, x509_key, 0)); ck_assert_int_eq(RHN_OK, r_jwk_init(&jwk)); ck_assert_int_eq(RHN_OK, r_jwk_import_from_gnutls_privkey(jwk, privkey)); gnutls_privkey_deinit(privkey); gnutls_x509_privkey_deinit(x509_key); r_jwk_free(jwk); gnutls_pubkey_init(&pubkey); data.data = (unsigned char *)rsa_2048_pub; data.size = sizeof(rsa_2048_pub); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_pubkey_import(pubkey, &data, GNUTLS_X509_FMT_PEM)); ck_assert_int_eq(RHN_OK, r_jwk_init(&jwk)); ck_assert_int_eq(RHN_OK, r_jwk_import_from_gnutls_pubkey(jwk, pubkey)); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); gnutls_x509_crt_init(&crt); data.data = (unsigned char *)x509_cert; data.size = sizeof(x509_cert); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)); ck_assert_int_eq(RHN_OK, r_jwk_init(&jwk)); ck_assert_int_eq(RHN_OK, r_jwk_import_from_gnutls_x509_crt(jwk, crt)); gnutls_x509_crt_deinit(crt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_import_from_x5u) { #ifdef R_WITH_CURL jwk_t * jwk; int type; unsigned int bits = 0; #endif struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7463, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_crt"), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); ck_assert_int_eq(bits, 3072); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_ecdsa_crt"), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #endif #endif o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_import_from_x5u_x5c_invalid) { #ifdef R_WITH_CURL jwk_t * jwk; #endif struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7463, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_priv", NULL, 0, &callback_x5u_rsa_priv, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_pubkey", NULL, 0, &callback_x5u_rsa_pubkey, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/error", NULL, 0, &callback_x5u_error, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_priv"), RHN_ERROR); ck_assert_int_eq(r_jwk_import_from_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_pubkey"), RHN_ERROR); ck_assert_int_eq(r_jwk_import_from_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/error"), RHN_ERROR); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_x5c(jwk, (const char *)rsa_2048_priv_der), RHN_ERROR); ck_assert_int_eq(r_jwk_import_from_x5c(jwk, (const char *)rsa_2048_pub_der), RHN_ERROR); ck_assert_int_eq(r_jwk_import_from_x5c(jwk, "ZXJyb3I="), RHN_ERROR); r_jwk_free(jwk); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_key_type) { jwk_t * jwk; int type; struct _u_instance instance; unsigned int bits = 0; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7464, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_eddsa_crt", NULL, 0, &callback_x5u_eddsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #endif bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2048); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2048); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 128); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_ne(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_REMOTE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2056); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #ifdef R_WITH_CURL bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_str), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_REMOTE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 3072); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #endif bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_only), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_REMOTE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2048); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_only_invalid_type), RHN_ERROR_PARAM); ck_assert_int_eq((type = r_jwk_key_type(jwk, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_REMOTE)), R_KEY_TYPE_NONE); ck_assert_int_eq(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #ifdef R_WITH_CURL bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_rsa_pub), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_SERVER_CERTIFICATE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 3072); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_large), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_ERROR_PARAM); r_jwk_free(jwk); #if GNUTLS_VERSION_NUMBER >= 0x030600 bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_ecdsa_pub), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_SERVER_CERTIFICATE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_eddsa_pub), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_ERROR_PARAM); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_SERVER_CERTIFICATE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); bits = 0; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5u_only_ecdsa_pub_invalid_type), RHN_OK); ck_assert_int_eq(r_jwk_is_valid_x5u(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_ERROR_PARAM); ck_assert_int_ne((type = r_jwk_key_type(jwk, &bits, R_FLAG_IGNORE_SERVER_CERTIFICATE)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 256); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_EDDSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk); #endif #endif o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_extract_pubkey) { jwk_t * jwk_privkey, * jwk_pubkey; int type; unsigned int bits = 0; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk_privkey, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, rsa_2048_priv, o_strlen((const char *)rsa_2048_priv)), RHN_OK); ck_assert_int_eq(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2048); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #if GNUTLS_VERSION_NUMBER >= 0x030600 bits = 0; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk_privkey, R_X509_TYPE_PRIVKEY, R_FORMAT_PEM, ecdsa_521_priv, o_strlen((const char *)ecdsa_521_priv)), RHN_OK); ck_assert_int_eq(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 521); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_RSA, 0); ck_assert_int_ne(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); #endif ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk_privkey, R_X509_TYPE_PUBKEY, R_FORMAT_PEM, rsa_2048_pub, o_strlen((const char *)rsa_2048_pub)), RHN_OK); ck_assert_int_ne(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_x5c_x5u_x5t_x5ts256_str), RHN_OK); ck_assert_int_eq(r_jwk_extract_pubkey(jwk_privkey, jwk_pubkey, 0), RHN_OK); ck_assert_int_ne((type = r_jwk_key_type(jwk_pubkey, &bits, 0)), R_KEY_TYPE_NONE); ck_assert_int_eq(bits, 2048); ck_assert_int_ne(type & R_KEY_TYPE_PUBLIC, 0); ck_assert_int_eq(type & R_KEY_TYPE_PRIVATE, 0); ck_assert_int_eq(type & R_KEY_TYPE_SYMMETRIC, 0); ck_assert_int_ne(type & R_KEY_TYPE_RSA, 0); ck_assert_int_eq(type & R_KEY_TYPE_EC, 0); ck_assert_int_eq(type & R_KEY_TYPE_HMAC, 0); ck_assert_int_eq(r_jwk_get_property_array_size(jwk_pubkey, "x5c"), r_jwk_get_property_array_size(jwk_privkey, "x5c")); ck_assert_str_eq(r_jwk_get_property_array(jwk_pubkey, "x5c", 0), r_jwk_get_property_array(jwk_privkey, "x5c", 0)); ck_assert_str_eq(r_jwk_get_property_str(jwk_pubkey, "x5u"), r_jwk_get_property_str(jwk_privkey, "x5u")); ck_assert_str_eq(r_jwk_get_property_str(jwk_pubkey, "x5t"), r_jwk_get_property_str(jwk_privkey, "x5t")); ck_assert_str_eq(r_jwk_get_property_str(jwk_pubkey, "x5t#S256"), r_jwk_get_property_str(jwk_privkey, "x5t#S256")); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_append_x5c) { jwk_t * jwk; char * http_cert = get_file_content(HTTPS_CERT_PEM); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, rsa_crt, o_strlen((const char *)rsa_crt)), RHN_OK); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 1); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 0), NULL); ck_assert_ptr_eq(r_jwk_get_property_array(jwk, "x5c", 1), NULL); ck_assert_int_eq(r_jwk_append_x5c(NULL, R_FORMAT_PEM, rsa_crt, o_strlen((const char *)rsa_crt)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_append_x5c(jwk, R_FORMAT_DER, rsa_crt, o_strlen((const char *)rsa_crt)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_append_x5c(jwk, R_FORMAT_PEM, NULL, o_strlen((const char *)rsa_crt)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_append_x5c(jwk, R_FORMAT_PEM, rsa_crt, o_strlen((const char *)rsa_crt)-30), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_append_x5c(jwk, R_FORMAT_PEM, rsa_crt, o_strlen((const char *)rsa_crt)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 1), NULL); ck_assert_ptr_eq(r_jwk_get_property_array(jwk, "x5c", 2), NULL); ck_assert_int_eq(r_jwk_append_x5c(jwk, R_FORMAT_PEM, (const unsigned char *)http_cert, o_strlen(http_cert)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 3); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 1), NULL); ck_assert_ptr_ne(r_jwk_get_property_array(jwk, "x5c", 2), NULL); ck_assert_ptr_eq(r_jwk_get_property_array(jwk, "x5c", 3), NULL); o_free(http_cert); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_parse_x5c) { jwk_t * jwk; char * cert_file; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content("cert/fullchain1.crt"), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); o_free(cert_file); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_validate_xc5_chain) { jwk_t * jwk; char * cert_file; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content(FULLCHAIN1_FILE), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, 0), RHN_OK); o_free(cert_file); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content(FULLCHAIN2_FILE), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, 0), RHN_OK); o_free(cert_file); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content(FULLCHAIN1_FILE), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)-30), RHN_ERROR_PARAM); o_free(cert_file); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content(FULLCHAIN_ERROR_FILE), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, 0), RHN_ERROR_INVALID); o_free(cert_file); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), -1); ck_assert_ptr_ne(cert_file = get_file_content(FULLCHAIN1_FILE), NULL); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, (const unsigned char *)cert_file, o_strlen(cert_file)), RHN_OK); ck_assert_int_eq(r_jwk_get_property_array_size(jwk, "x5c"), 2); ck_assert_int_eq(r_jwk_append_property_array(jwk, "x5c", "error"), RHN_OK); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, 0), RHN_ERROR_INVALID); o_free(cert_file); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_validate_x5u_chain) { #ifdef R_WITH_CURL jwk_t * jwk; #endif struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7465, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_fullchain1", NULL, 0, &callback_x5u_fullchain1, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_fullchain2", NULL, 0, &callback_x5u_fullchain2, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_fullchain1_trucated", NULL, 0, &callback_x5u_fullchain1_trucated, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_fullchain_error", NULL, 0, &callback_x5u_fullchain_error, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, x5u_fullchain1_crt), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, x5u_fullchain2_crt), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, x5u_fullchain_error_crt), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_ERROR_INVALID); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_ptr_eq(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, x5u_fullchain1_trucated_crt), RHN_OK); ck_assert_ptr_ne(r_jwk_get_property_str(jwk, "x5u"), NULL); ck_assert_int_eq(r_jwk_validate_x5c_chain(jwk, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_ERROR_INVALID); r_jwk_free(jwk); #endif o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_quick_import) { jwk_t * jwk; json_t * j_input; unsigned char der_decoded[4096]; size_t der_dec_len = 0; struct _u_instance instance; char * http_key, * http_cert; gnutls_privkey_t privkey; gnutls_x509_privkey_t x509_key; gnutls_pubkey_t pubkey; gnutls_x509_crt_t crt; gnutls_datum_t data; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7463, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str)); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str_invalid_kty)); ck_assert_ptr_ne(NULL, j_input = json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL)); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_JSON_T, j_input)); json_decref(j_input); r_jwk_free(jwk); ck_assert_ptr_ne(NULL, j_input = json_loads(jwk_pubkey_ecdsa_str_invalid_kty, JSON_DECODE_ANY, NULL)); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_JSON_T, j_input)); json_decref(j_input); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_PEM, R_X509_TYPE_PUBKEY, rsa_2048_pub, sizeof(rsa_2048_pub))); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_PEM, R_X509_TYPE_PUBKEY, error_pem, sizeof(error_pem))); ck_assert_int_eq(o_base64_decode(rsa_2048_pub_der, o_strlen((const char *)rsa_2048_pub_der), der_decoded, &der_dec_len), 1); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_DER, R_X509_TYPE_PUBKEY, der_decoded, der_dec_len)); ck_assert_int_eq(r_jwk_is_valid(jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_DER, R_X509_TYPE_PUBKEY, der_decoded+40, der_dec_len-40)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_privkey_init(&privkey)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_init(&x509_key)); data.data = (unsigned char *)rsa_2048_priv; data.size = sizeof(rsa_2048_priv); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_import(x509_key, &data, GNUTLS_X509_FMT_PEM)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_privkey_import_x509(privkey, x509_key, 0)); ck_assert_ptr_ne(RHN_OK, jwk = r_jwk_quick_import(R_IMPORT_G_PRIVKEY, privkey)); gnutls_privkey_deinit(privkey); gnutls_x509_privkey_deinit(x509_key); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_G_PRIVKEY, NULL)); gnutls_pubkey_init(&pubkey); data.data = (unsigned char *)rsa_2048_pub; data.size = sizeof(rsa_2048_pub); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_pubkey_import(pubkey, &data, GNUTLS_X509_FMT_PEM)); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_G_PUBKEY, pubkey)); gnutls_pubkey_deinit(pubkey); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_G_PUBKEY, NULL)); gnutls_x509_crt_init(&crt); data.data = (unsigned char *)x509_cert; data.size = sizeof(x509_cert); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_G_CERT, crt)); gnutls_x509_crt_deinit(crt); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_G_CERT, NULL)); #ifdef R_WITH_CURL ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_crt")); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/error")); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_ecdsa_crt")); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/error")); #endif #endif ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_SYMKEY, symmetric_key, sizeof(symmetric_key))); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jwk_quick_import(R_IMPORT_SYMKEY, NULL, sizeof(symmetric_key))); ck_assert_ptr_ne(NULL, jwk = r_jwk_quick_import(R_IMPORT_PASSWORD, symmetric_key)); r_jwk_free(jwk); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWK import function tests"); tc_core = tcase_create("test_rhonabwy_import"); tcase_add_test(tc_core, test_rhonabwy_import_from_json_str); tcase_add_test(tc_core, test_rhonabwy_import_from_json_t); tcase_add_test(tc_core, test_rhonabwy_import_from_pem); tcase_add_test(tc_core, test_rhonabwy_import_from_der); tcase_add_test(tc_core, test_rhonabwy_import_from_gnutls); tcase_add_test(tc_core, test_rhonabwy_import_from_x5u); tcase_add_test(tc_core, test_rhonabwy_import_from_x5u_x5c_invalid); tcase_add_test(tc_core, test_rhonabwy_key_type); tcase_add_test(tc_core, test_rhonabwy_extract_pubkey); tcase_add_test(tc_core, test_rhonabwy_append_x5c); tcase_add_test(tc_core, test_rhonabwy_parse_x5c); tcase_add_test(tc_core, test_rhonabwy_validate_xc5_chain); tcase_add_test(tc_core, test_rhonabwy_validate_x5u_chain); tcase_add_test(tc_core, test_rhonabwy_quick_import); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWK import tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwks_core.c000066400000000000000000001321761452472117100165550ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #include const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"grut\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2016-06-22\"}"; const char jwk_pubkey_rsa_x5u_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2012-04-29\",\"x5u\":\"https://www.example.com/x509\"}"; const char jwk_pubkey_rsa_x5c_str[] = "{\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"1b94c\",\"n\":\"AL64zn8_QnHYMeZ0LncoXaEde1fiLm1jHjmQsF_449IYALM9if6amFtPDy2"\ "yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf_u3WG7K-IiZhtELto_A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quG"\ "mFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel-W1GC8ugMhyr4_p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPp"\ "njL1XyW-oyVVkaZdklLQp2Btgt9qr21m42f4wTw-Xrp6rCKNb0\",\"e\":\"AQAB\",\"x5c\":[\"MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSI"\ "b3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQY"\ "DVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UE"\ "BxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPA"\ "DCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3W"\ "G7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/"\ "p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCK"\ "Nb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9A"\ "qBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKV"\ "MJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5"\ "MPvACWpkA6SdS4xSvdXK3IVfOWA==\"]}"; const char jwk_pubkey_rsa_str_invalid_n[] = "{\"kty\":\"RSA\",\"n\":42,\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2010-04-29\"}"; const unsigned char rsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIEWTCCAsGgAwIBAgIUJyAFwqkMTppNiyU8gFOK4WUC1GgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0xOTEyMDYxMzU1MzlaFw0yMDExMjAxMzU1MzlaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MIIBojANBgkqhkiG9w0BAQEFAAOC\n" "AY8AMIIBigKCAYEAsUWjL3wK1B/dQbXbhSXaodF0gXMNlZg3ZecjZIJOKgXGDVOn\n" "V0ly4evW8xkn8F2gC3TYJXik7efdhGdiaYul9kyzpPBr53ELHMmAeI/I1rnF4pgI\n" "wfN1vBsaDwJw9w0R6FQ9fxDUIte47WdElEHhtST9V874mMehsSUG4xM2qiBvvbWw\n" "X0KCyKk6BY/CdyljUjAPUShcVysKUTyfefew38KUVTVpk2vWLlN+a41iC/gxGvLt\n" "H142LDiDx/s+Kh37f4paD2zsEw5McF81eiKTAfrraIC1Gj2BxyEj6n2EjqyI+NFR\n" "sSUmqfPoFgiMzlEWj4P8AwvfE9jbjXz/E0GOISiXt4L+06U7rLoGHFri5oVI6KUk\n" "LAOwwwTri+ikeQFx68IKvhytBiX1O+XHh51JZyyC+fcKKN+/ATgGKIiR63M5UWYx\n" "O2JkVkPvpzORKJUivePFQbkEcxYZb9VqoVZ04sfpfGb3h2douzBrKbkDP/Jf+O0J\n" "PKDTltrUJOpZbYhVAgMBAAGjdjB0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYI\n" "KwYBBQUHAwIwDwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUiZGaRSyAyraAdeo5\n" "wJc+0Ks7IOcwHwYDVR0jBBgwFoAU0marYk/GnTVDeDbie2BY15qCu0QwDQYJKoZI\n" "hvcNAQELBQADggGBAGINVR+lskHnxkYvPkgCQG+nGqovI28W6rtx8a5xM/6rtsVs\n" "5jCu1nnJd32YNjDsySxsbkhXjW0WjGR7cEsnmcOITeP4kLLVzh1vm6sZa/9vX1fh\n" "M5pTUTYTHYozl6TA85CtBd7oC/AB2Gwh5q1kJ3wmGwmCY8mqPftP+plyFTSbCwAH\n" "BZSfCgsMpffILDzPgViU54BehfpfljZcmGJnnGKEnTRvUr84/NlmKEdhw9rKyod5\n" "KKieGneVzpPeiyXrzUEJuGkmLtVLpvNdDdB5+6rN0hK+bFyB3NA+gASIiekuM7Q+\n" "4RgroWwTF7fq1XUhX3aexOI2eTx0B2bBpD28TcYvqo6Y+aBKHVbo8gnbMr5IoIkI\n" "rYz8CXrbbZFRilsHRQgzyEmTq/Wp0GVt/zakMF7suA8nl/AQcKDOWGBnEFc+okAe\n" "K0P/4R4UnQSPU8SfsFBGxm4PXN4BZktZ10LC/xKMJBkdSD0vTLce9Sx7xR4PUIaN\n" "n2x0D4zZG7px73kB0Q==\n" "-----END CERTIFICATE-----"; const unsigned char ecdsa_crt[] = "-----BEGIN CERTIFICATE-----\n" "MIIDNjCCAZ6gAwIBAgIUDzxOEj+8WUrLa1M97arwkEo5gEwwDQYJKoZIhvcNAQEL\n" "BQAwMjEbMBkGA1UEAwwSZ2xld2x3eWRfcGFja2VkX2NhMRMwEQYDVQQKEwpiYWJl\n" "bG91ZXN0MB4XDTE5MTIwNjEzNTYxM1oXDTIwMTEyMDEzNTYxM1owYDEYMBYGA1UE\n" "AwwPZ2xld2x3eWRfcGFja2VkMSIwIAYDVQQLExlBdXRoZW50aWNhdG9yIEF0dGVz\n" "dGF0aW9uMRMwEQYDVQQKEwpiYWJlbG91ZXN0MQswCQYDVQQGEwJDQTBZMBMGByqG\n" "SM49AgEGCCqGSM49AwEHA0IABOjeoVGraskp+jax8TTOXy92o6PGGN2Tl3XshqN/\n" "XZnfkyxxLxKvJ0igfQ4Qy4/9w8PGjVilnY4zR3y25VJ7KLejYTBfMAwGA1UdEwEB\n" "/wQCMAAwDwYDVR0PAQH/BAUDAweAADAdBgNVHQ4EFgQU34GPDg2bLIneLKIfjYjU\n" "NuiU170wHwYDVR0jBBgwFoAUlOaykWFTL+EV/0PHksB2Dh1k1KAwDQYJKoZIhvcN\n" "AQELBQADggGBAFHNuUQUkZaunXfV3qSemhlyHH1hnt6YXJLIl2IKugg/mg8hga2C\n" "dBN7MMcVYpXtNI8AKfSIZRu3v16OMIajCIh7PYGa5asbJZgtOkbvfc58eaWhzl8U\n" "B0j89aGlntZs3WWINYgqfzBS6Pw3SJ5iVTpS+xH2JSWxZYX3uvEDkVkw1VjmyyN3\n" "ZX0tkFTKQB3GNFZwesxoRKizsu8r+tCIqgfqRTG7FIOa/UB3MXVClA//+TCnW2RI\n" "48JzjY/YhO54pWVsblHAQwMOmuHlJrnfLFPvBqFx5mi8Z5jHfZipsNksIteKFdtG\n" "3FvjQYIj2wJM9k7XHrQ3szxwvq9Ss2cyCBPArrKVpBTibypIkON9R2Peocr3HkUx\n" "YYhu3pNumaSdGzL0r7A2iGIXy9orIAQ8f1i7iaYDBWs/PkJ340iHRZtSuez8F+GN\n" "NUV15utv9AMvahkCI5ZS71TAv4AFjsZpsvYuCvpUUPdZpC+r9lk8H1wa4VA+mujL\n" "2Yxh1fFV7ONNjA==\n" "-----END CERTIFICATE-----"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; const unsigned char rsa_2048_pub_der[] = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\ uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\ iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\ ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\ 6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\ K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\ BwIDAQAB"; const unsigned char rsa_2048_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\n" "iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\n" "lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\n" "Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\n" "TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\n" "45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\n" "2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\n" "n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\n" "wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\n" "z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\n" "3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\n" "UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\n" "DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\n" "DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\n" "m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\n" "cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\n" "1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\n" "I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\n" "INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\n" "vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\n" "Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\n" "TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\n" "+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\n" "mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\n" "LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\n" "tEOtzsP5GMDYVlEp1jYSjzQ=\n" "-----END PRIVATE KEY-----\n"; const unsigned char x509_cert[] = "-----BEGIN CERTIFICATE-----\n" "MIIBejCCASGgAwIBAgIUUmwvBcKwJSWZMLC9xtUYQhh/YicwCgYIKoZIzj0EAwIw\n" "EzERMA8GA1UEAwwIZ2xld2x3eWQwHhcNMTkwNjEyMTY0MjExWhcNMjkwNjA5MTY0\n" "MjExWjATMREwDwYDVQQDDAhnbGV3bHd5ZDBZMBMGByqGSM49AgEGCCqGSM49AwEH\n" "A0IABKP9Eu2Rzt15pKqriLiniryG9zsabCq+aNneB+mmIDwRkjaqpKeGwztLEHBG\n" "TrHh9poToHkaxUuFE/wVD+9GscGjUzBRMB0GA1UdDgQWBBQQv5dX9gxGFfEDD2Zu\n" "jZQT3FTitDAfBgNVHSMEGDAWgBQQv5dX9gxGFfEDD2ZujZQT3FTitDAPBgNVHRMB\n" "Af8EBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIBqkd3kqcKZ/gEsnAVi5sQR3gB04\n" "U8JNjzPwv//HmV/FAiBT45X52j1G6QGPg82twWR7CZiHbJPe26drWkkoDeT/QQ==\n" "-----END CERTIFICATE-----\n"; const unsigned char error_pem[] = "-----BEGIN ERROR FROM OUTER SPACE-----"; const unsigned char symmetric_key[] = "secret"; #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_jwks_ok (const struct _u_request * request, struct _u_response * response, void * user_data) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); json_t * j_jwks = json_loads(jwks_str, JSON_DECODE_ANY, NULL); ulfius_set_json_body_response(response, 200, j_jwks); json_decref(j_jwks); o_free(jwks_str); return U_CALLBACK_CONTINUE; } int callback_jwks_error_content_no_jwks (const struct _u_request * request, struct _u_response * response, void * user_data) { json_t * j_jwks = json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL); ulfius_set_json_body_response(response, 200, j_jwks); json_decref(j_jwks); return U_CALLBACK_CONTINUE; } int callback_jwks_error_content_no_json (const struct _u_request * request, struct _u_response * response, void * user_data) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); ulfius_set_string_body_response(response, 200, jwks_str); o_free(jwks_str); return U_CALLBACK_CONTINUE; } int callback_jwks_error_status (const struct _u_request * request, struct _u_response * response, void * user_data) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); json_t * j_jwks = json_loads(jwks_str, JSON_DECODE_ANY, NULL); ulfius_set_json_body_response(response, 400, j_jwks); json_decref(j_jwks); o_free(jwks_str); return U_CALLBACK_CONTINUE; } int callback_jwks_redirect (const struct _u_request * request, struct _u_response * response, void * user_data) { u_map_put(response->map_header, "Location", "jwks_ok"); response->status = 302; return U_CALLBACK_CONTINUE; } int callback_jwks_too_large (const struct _u_request * request, struct _u_response * response, void * user_data) { json_t * j_jwks = json_pack("{s[]}", "keys"); int i; for (i=0; i<1024; i++) { json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_pubkey_ecdsa_str, JSON_DECODE_ANY, NULL)); json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_privkey_ecdsa_str, JSON_DECODE_ANY, NULL)); json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_pubkey_rsa_str, JSON_DECODE_ANY, NULL)); json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_privkey_rsa_str, JSON_DECODE_ANY, NULL)); json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_pubkey_rsa_x5u_str, JSON_DECODE_ANY, NULL)); json_array_append_new(json_object_get(j_jwks, "keys"), json_loads(jwk_pubkey_rsa_x5c_str, JSON_DECODE_ANY, NULL)); } ulfius_set_json_body_response(response, 200, j_jwks); ck_assert_int_gt(response->binary_body_length, R_MAX_BODY_SIZE); json_decref(j_jwks); return U_CALLBACK_CONTINUE; } int callback_x5u_rsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)rsa_crt); return U_CALLBACK_CONTINUE; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)ecdsa_crt); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_init_jwks) { jwks_t * jwks; ck_assert_int_eq(r_jwks_init(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_is_valid) { jwks_t * jwks; jwk_t * jwk; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_is_valid(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 0); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 1); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 2); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 3); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 4); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_set_property_str(jwk, "kty", "error"), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 5); ck_assert_int_eq(r_jwks_is_valid(jwks), RHN_ERROR_PARAM); r_jwk_free(jwk); r_jwks_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_export_str) { jwks_t * jwks; jwk_t * jwk; char * out; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 2); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_json_str(jwks, 0)), NULL); o_free(out); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_export_json_t) { jwks_t * jwks; jwk_t * jwk; json_t * j_out; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 2); r_jwk_free(jwk); ck_assert_ptr_ne((j_out = r_jwks_export_to_json_t(jwks)), NULL); json_decref(j_out); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_export_privkey) { jwks_t * jwks; jwk_t * jwk; gnutls_privkey_t * out = NULL; size_t len = 0; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_privkey(jwks, &len)), NULL); ck_assert_int_eq(len, 1); ck_assert_ptr_ne(out[0], NULL); gnutls_privkey_deinit(out[0]); o_free(out); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_privkey(jwks, &len)), NULL); ck_assert_int_eq(len, 2); ck_assert_ptr_ne(out[0], NULL); ck_assert_ptr_eq(out[1], NULL); gnutls_privkey_deinit(out[0]); o_free(out); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_privkey(jwks, &len)), NULL); ck_assert_int_eq(len, 3); ck_assert_ptr_ne(out[0], NULL); ck_assert_ptr_eq(out[1], NULL); ck_assert_ptr_ne(out[2], NULL); gnutls_privkey_deinit(out[0]); gnutls_privkey_deinit(out[2]); o_free(out); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_export_pubkey) { jwks_t * jwks; jwk_t * jwk; gnutls_pubkey_t * out = NULL; size_t len = 0; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_pubkey(jwks, &len, 0)), NULL); ck_assert_int_eq(len, 1); ck_assert_ptr_ne(out[0], NULL); gnutls_pubkey_deinit(out[0]); o_free(out); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_pubkey(jwks, &len, 0)), NULL); ck_assert_int_eq(len, 2); ck_assert_ptr_ne(out[0], NULL); ck_assert_ptr_ne(out[1], NULL); gnutls_pubkey_deinit(out[0]); gnutls_pubkey_deinit(out[1]); o_free(out); #else ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_pubkey(jwks, &len, 0)), NULL); ck_assert_int_eq(len, 1); ck_assert_ptr_ne(out[0], NULL); gnutls_pubkey_deinit(out[0]); o_free(out); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_x5c_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_pubkey(jwks, &len, 0)), NULL); ck_assert_int_eq(len, 2); ck_assert_ptr_ne(out[0], NULL); ck_assert_ptr_ne(out[1], NULL); gnutls_pubkey_deinit(out[0]); gnutls_pubkey_deinit(out[1]); o_free(out); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_ne((out = r_jwks_export_to_gnutls_pubkey(jwks, &len, 0)), NULL); ck_assert_int_eq(len, 3); ck_assert_ptr_ne(out[0], NULL); ck_assert_ptr_ne(out[1], NULL); ck_assert_ptr_ne(out[2], NULL); gnutls_pubkey_deinit(out[0]); gnutls_pubkey_deinit(out[1]); gnutls_pubkey_deinit(out[2]); o_free(out); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_export_pem) { jwks_t * jwks; jwk_t * jwk; unsigned char out[4096]; size_t len = 4096; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); #endif ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwks_export_to_pem_der(jwks, R_FORMAT_PEM, out, &len, 0), RHN_OK); ck_assert_int_lt(len, 4096); len = 42; ck_assert_int_eq(r_jwks_export_to_pem_der(jwks, R_FORMAT_PEM, out, &len, 0), RHN_ERROR_PARAM); r_jwk_free(jwks); } END_TEST START_TEST(test_rhonabwy_jwks_import) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(NULL, jwks_str), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_import_from_json_str(NULL, NULL), RHN_ERROR_PARAM); ck_assert_ptr_ne(jwks_str, NULL); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, "{error}"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 4); r_jwk_free(jwks); o_free(jwks_str); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_str_invalid_n); ck_assert_ptr_ne(jwks_str, NULL); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, jwks_str), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_size(jwks), 3); r_jwk_free(jwks); o_free(jwks_str); } END_TEST START_TEST(test_rhonabwy_jwks_import_uri) { struct _u_instance instance; #ifdef R_WITH_CURL jwks_t * jwks = NULL; #endif ck_assert_int_eq(ulfius_init_instance(&instance, 7462, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_ok", NULL, 0, &callback_jwks_ok, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_error_content_no_jwks", NULL, 0, &callback_jwks_error_content_no_jwks, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_error_content_no_json", NULL, 0, &callback_jwks_error_content_no_json, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_error_status", NULL, 0, &callback_jwks_error_status, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_redirect", NULL, 0, &callback_jwks_redirect, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_too_large", NULL, 0, &callback_jwks_too_large, NULL), U_OK); #ifdef R_WITH_CURL ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(NULL, "http://localhost:7462/jwks_ok", 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_import_from_uri(jwks, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_import_from_uri(NULL, NULL, 0), RHN_ERROR_PARAM); r_jwk_free(jwks); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_ok", 0), RHN_ERROR); r_jwk_free(jwks); ck_assert_int_eq(ulfius_start_framework(&instance), U_OK); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_error_content_no_jwks", 0), RHN_ERROR_PARAM); r_jwk_free(jwks); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_error_content_no_json", 0), RHN_ERROR); r_jwk_free(jwks); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_error_status", 0), RHN_ERROR); r_jwk_free(jwks); // This test works if R_MAX_BODY_SIZE has the default value of 4MB ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_too_large", 0), RHN_ERROR); r_jwk_free(jwks); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_redirect", 0), RHN_ERROR); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_redirect", R_FLAG_FOLLOW_REDIRECT), RHN_OK); r_jwk_free(jwks); ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_uri(jwks, "http://localhost:7462/jwks_ok", 0), RHN_OK); r_jwk_free(jwks); ulfius_stop_framework(&instance); #endif ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_jwks_get_by_kid) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks; jwk_t * jwk; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 4); ck_assert_ptr_eq(r_jwks_get_by_kid(jwks, ""), NULL); ck_assert_ptr_eq(r_jwks_get_by_kid(jwks, NULL), NULL); ck_assert_ptr_eq(r_jwks_get_by_kid(jwks, "error"), NULL); jwk = r_jwks_get_by_kid(jwks, "1"); ck_assert_ptr_ne(jwk, NULL); r_jwk_free(jwk); r_jwk_free(jwks); o_free(jwks_str); } END_TEST START_TEST(test_rhonabwy_jwks_equal) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str), * jwks_str2 = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks1, * jwks2; ck_assert_int_eq(r_jwks_init(&jwks1), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks2), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks1, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks2, jwks_str), RHN_OK); ck_assert_int_ne(r_jwks_equal(jwks1, jwks2), 0); r_jwk_free(jwks1); r_jwk_free(jwks2); ck_assert_int_eq(r_jwks_init(&jwks1), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks2), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks1, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks2, jwks_str2), RHN_OK); ck_assert_int_eq(r_jwks_equal(jwks1, jwks2), 0); r_jwk_free(jwks1); r_jwk_free(jwks2); ck_assert_int_eq(r_jwks_init(&jwks1), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks2), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks1, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_equal(jwks1, jwks2), 0); r_jwk_free(jwks1); r_jwk_free(jwks2); ck_assert_int_eq(r_jwks_init(&jwks1), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks2), RHN_OK); ck_assert_int_ne(r_jwks_equal(jwks1, jwks2), 0); r_jwk_free(jwks1); r_jwk_free(jwks2); o_free(jwks_str); o_free(jwks_str2); } END_TEST START_TEST(test_rhonabwy_jwks_empty) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks; ck_assert_int_eq(r_jwks_init(&jwks), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks, jwks_str), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 4); ck_assert_int_eq(r_jwks_empty(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwks_empty(jwks), RHN_OK); ck_assert_int_eq(r_jwks_size(jwks), 0); r_jwk_free(jwks); o_free(jwks_str); } END_TEST START_TEST(test_rhonabwy_jwks_copy) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks1, * jwks2; ck_assert_int_eq(r_jwks_init(&jwks1), RHN_OK); ck_assert_int_eq(r_jwks_import_from_json_str(jwks1, jwks_str), RHN_OK); ck_assert_ptr_ne((jwks2 = r_jwks_copy(jwks1)), NULL); ck_assert_int_ne(r_jwks_equal(jwks1, jwks2), 0); r_jwk_free(jwks1); r_jwk_free(jwks2); o_free(jwks_str); } END_TEST START_TEST(test_rhonabwy_jwks_quick_import) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); json_t * jwks_j = json_loads(jwks_str, JSON_DECODE_ANY, NULL), * jwk_j = json_loads(jwk_pubkey_rsa_str, JSON_DECODE_ANY, NULL); jwks_t * jwks; unsigned char der_decoded[4096]; size_t der_dec_len = 0; struct _u_instance instance; char * http_key, * http_cert; gnutls_privkey_t privkey; gnutls_x509_privkey_t x509_key; gnutls_pubkey_t pubkey; gnutls_x509_crt_t crt; gnutls_datum_t data; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7463, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_rsa_crt", NULL, 0, &callback_x5u_rsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u_ecdsa_crt", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jwks_ok", NULL, 0, &callback_jwks_ok, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, jwks_str, R_IMPORT_NONE)); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str, R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_T, jwks_j, R_IMPORT_NONE)); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_T, jwk_j, R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_PEM, R_X509_TYPE_PUBKEY, rsa_2048_pub, sizeof(rsa_2048_pub), R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_PEM, R_X509_TYPE_PUBKEY, error_pem, sizeof(error_pem), R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(o_base64_decode(rsa_2048_pub_der, o_strlen((const char *)rsa_2048_pub_der), der_decoded, &der_dec_len), 1); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_DER, R_X509_TYPE_PUBKEY, der_decoded, der_dec_len, R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_DER, R_X509_TYPE_PUBKEY, der_decoded+40, der_dec_len-40, R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_privkey_init(&privkey)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_init(&x509_key)); data.data = (unsigned char *)rsa_2048_priv; data.size = sizeof(rsa_2048_priv); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_privkey_import(x509_key, &data, GNUTLS_X509_FMT_PEM)); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_privkey_import_x509(privkey, x509_key, 0)); ck_assert_ptr_ne(RHN_OK, jwks = r_jwks_quick_import(R_IMPORT_G_PRIVKEY, privkey, R_IMPORT_NONE)); gnutls_privkey_deinit(privkey); gnutls_x509_privkey_deinit(x509_key); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_G_PRIVKEY, NULL, R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); gnutls_pubkey_init(&pubkey); data.data = (unsigned char *)rsa_2048_pub; data.size = sizeof(rsa_2048_pub); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_pubkey_import(pubkey, &data, GNUTLS_X509_FMT_PEM)); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_G_PUBKEY, pubkey, R_IMPORT_NONE)); gnutls_pubkey_deinit(pubkey); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_G_PUBKEY, NULL, R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); gnutls_x509_crt_init(&crt); data.data = (unsigned char *)x509_cert; data.size = sizeof(x509_cert); ck_assert_int_eq(GNUTLS_E_SUCCESS, gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_PEM)); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_G_CERT, crt, R_IMPORT_NONE)); gnutls_x509_crt_deinit(crt); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_G_CERT, NULL, R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, NULL, R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "{\"error", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "{\"error\":\"error\"", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "{\"error\":\"error\"}", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "{\"error\":42}", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "[\"error\",\"error\"]", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, "[\"error\",\"error\"]", R_IMPORT_JSON_STR, jwks_str, R_IMPORT_JSON_STR, jwk_pubkey_ecdsa_str, R_IMPORT_NONE)); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); #ifdef R_WITH_CURL ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_crt", R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/error", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_ecdsa_crt", R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/error", R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); #endif #endif ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_SYMKEY, symmetric_key, sizeof(symmetric_key), R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_SYMKEY, NULL, sizeof(symmetric_key), R_IMPORT_NONE)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_PASSWORD, symmetric_key, R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_T, jwk_j, R_IMPORT_JSON_T, jwks_j, R_IMPORT_NONE)); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_T, jwk_j, R_IMPORT_JSON_T, NULL, R_IMPORT_NONE)); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); #ifdef R_WITH_CURL ck_assert_ptr_ne(NULL, jwks = r_jwks_quick_import(R_IMPORT_JSON_T, jwk_j, R_IMPORT_JSON_T, jwks_j, R_IMPORT_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE, "https://localhost:7463/x5u_rsa_crt", R_IMPORT_NONE)); ck_assert_int_eq(6, r_jwks_size(jwks)); r_jwks_free(jwks); #endif json_decref(jwks_j); json_decref(jwk_j); o_free(jwks_str); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_jwks_search) { char * jwks_str = msprintf("{\"keys\":[%s,%s,%s,%s]}", jwk_pubkey_ecdsa_str, jwk_pubkey_rsa_str, jwk_pubkey_rsa_x5u_str, jwk_pubkey_rsa_x5c_str); jwks_t * jwks = r_jwks_quick_import(R_IMPORT_JSON_STR, jwks_str, R_IMPORT_NONE), * jwks_ret; json_t * j_match; const char match_empty[] = "{}", match_invalid[] = "error", match_kty_rsa[] = "{\"kty\":\"RSA\"}", match_kty_ec[] = "{\"kty\":\"EC\"}", match_kty_oct[] = "{\"kty\":\"oct\"}", match_kty_rsa_alg_rs256[] = "{\"kty\":\"RSA\",\"alg\":\"RS256\"}", match_kty_rsa_n[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX" "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6" "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\"}", match_kty_rsa_alg_ps256[] = "{\"kty\":\"RSA\",\"alg\":\"PS256\"}"; ck_assert_int_eq(4, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_empty)))); r_jwks_free(jwks_ret); ck_assert_int_eq(0, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_invalid)))); r_jwks_free(jwks_ret); ck_assert_ptr_ne(NULL, j_match = json_loads(match_kty_rsa, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(3, r_jwks_size((jwks_ret = r_jwks_search_json_t(jwks, j_match)))); r_jwks_free(jwks_ret); json_decref(j_match); ck_assert_int_eq(1, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_kty_ec)))); r_jwks_free(jwks_ret); ck_assert_int_eq(0, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_kty_oct)))); r_jwks_free(jwks_ret); ck_assert_int_eq(2, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_kty_rsa_alg_rs256)))); r_jwks_free(jwks_ret); ck_assert_int_eq(2, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_kty_rsa_n)))); r_jwks_free(jwks_ret); ck_assert_int_eq(0, r_jwks_size((jwks_ret = r_jwks_search_json_str(jwks, match_kty_rsa_alg_ps256)))); r_jwks_free(jwks_ret); r_jwks_free(jwks); o_free(jwks_str); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWKS core function tests"); tc_core = tcase_create("test_rhonabwy_jwks"); tcase_add_test(tc_core, test_rhonabwy_init_jwks); tcase_add_test(tc_core, test_rhonabwy_jwks_is_valid); tcase_add_test(tc_core, test_rhonabwy_jwks_export_str); tcase_add_test(tc_core, test_rhonabwy_jwks_export_json_t); tcase_add_test(tc_core, test_rhonabwy_jwks_export_privkey); tcase_add_test(tc_core, test_rhonabwy_jwks_export_pubkey); tcase_add_test(tc_core, test_rhonabwy_jwks_export_pem); tcase_add_test(tc_core, test_rhonabwy_jwks_import); tcase_add_test(tc_core, test_rhonabwy_jwks_import_uri); tcase_add_test(tc_core, test_rhonabwy_jwks_get_by_kid); tcase_add_test(tc_core, test_rhonabwy_jwks_equal); tcase_add_test(tc_core, test_rhonabwy_jwks_empty); tcase_add_test(tc_core, test_rhonabwy_jwks_copy); tcase_add_test(tc_core, test_rhonabwy_jwks_quick_import); tcase_add_test(tc_core, test_rhonabwy_jwks_search); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWKS jwks tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_core.c000066400000000000000000002621141452472117100163760ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define HUGE_PAYLOAD "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis efficitur lectus sit amet libero gravida eleifend. Nulla aliquam accumsan erat, quis tincidunt purus ultricies eu. Aenean eu dui ac diam placerat mollis. Duis eget tempor ipsum, vel ullamcorper purus. Ut eget quam vehicula, congue urna vel, dictum risus. Duis tristique est sed diam lobortis commodo. Proin et urna in odio malesuada sagittis. Donec lectus ligula, porttitor sed lorem ut, malesuada posuere neque. Nullam et nisl a felis congue mattis id non lectus.\ Quisque viverra hendrerit malesuada. Integer sollicitudin magna purus, in dignissim eros ullamcorper et. Praesent dignissim metus neque, eget tempor dolor tincidunt egestas. Nulla odio risus, tincidunt et egestas aliquet, pellentesque et eros. Etiam mattis orci a dui efficitur pharetra. Donec fermentum sem sed lacus finibus, nec luctus nisl vulputate. Donec sodales, nisi sed posuere maximus, lectus elit fermentum sapien, quis volutpat risus nisl vel dui. In vitae ante diam.\ Vivamus a nisl quam. Proin in lectus nunc. Aliquam condimentum tellus non feugiat aliquam. Nulla eu mi ligula. Proin auctor varius massa sed consectetur. Nulla et ligula pellentesque, egestas dui eu, gravida arcu. Maecenas vehicula feugiat tincidunt. Aenean sed sollicitudin ex. Cras luctus facilisis erat eu pharetra. Vestibulum interdum consequat tellus nec sagittis. Aliquam tincidunt eget lectus non bibendum. Mauris ut consectetur diam.\ Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed lorem lectus, ullamcorper consectetur quam ut, pharetra consectetur diam. Suspendisse eu erat quis nunc imperdiet lacinia vitae id arcu. Fusce non euismod urna. Aenean lacinia porta tellus nec rutrum. Aliquam est magna, aliquam non hendrerit eget, scelerisque quis sapien. Quisque consectetur et lacus non dapibus. Duis diam purus, vulputate convallis faucibus in, rutrum quis mi. Sed sed magna eget tellus semper suscipit a in augue.\ Aenean vitae tortor quam. Praesent pulvinar nulla a nisi egestas, laoreet tempus mauris ullamcorper. Nam vulputate molestie velit, quis laoreet felis suscipit euismod. Pellentesque a enim dapibus, tincidunt lorem vel, suscipit turpis. Phasellus id metus vehicula, luctus sem nec, maximus purus. Duis dictum elit quam, quis rhoncus ex ullamcorper ut. Donec fringilla augue vitae vestibulum maximus. Mauris vel arcu eget arcu bibendum ornare." #define HS256_TOKEN "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_UNSECURE "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." #define HS256_TOKEN_INVALID_HEADER "eyJhbGciOiJIUzI1NiIsImtpZCI6Ij.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_INVALID_HEADER_B64 ";error;.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_INVALID_PAYLOAD_B64 "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.;error;.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_INVALID_DOTS "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQVGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_EMPTY_HEADER ".VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_EMPTY_PAYLOAD "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ..PdtqfpescIy_55JZ4PbRKp_nTbbVJik1Bs7S3nr99vQ" #define HS256_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." #define UNSECURE_TOKEN "eyJhbGciOiJub25lIn0.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0Cg\"}"; #define ANDROID_SAFETYNET_JWT "eyJhbGciOiJSUzI1NiIsIng1YyI6WyJNSUlGa2pDQ0JIcWdBd0lCQWdJUVJYcm9OMFpPZFJrQkFBQUFBQVB1bnpBTkJna3Foa2lHOXcwQkFRc0ZBREJDTVFz"\ "d0NRWURWUVFHRXdKVlV6RWVNQndHQTFVRUNoTVZSMjl2WjJ4bElGUnlkWE4wSUZObGNuWnBZMlZ6TVJNd0VRWURWUVFERXdwSFZGTWdRMEVnTVU4eE1CNFhE"\ "VEU0TVRBeE1EQTNNVGswTlZvWERURTVNVEF3T1RBM01UazBOVm93YkRFTE1Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBZ1RDa05oYkdsbWIzSnVhV0V4RmpB"\ "VUJnTlZCQWNURFUxdmRXNTBZV2x1SUZacFpYY3hFekFSQmdOVkJBb1RDa2R2YjJkc1pTQk1URU14R3pBWkJnTlZCQU1URW1GMGRHVnpkQzVoYm1SeWIybGtM"\ "bU52YlRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTmpYa3owZUsxU0U0bSsvRzV3T28rWEdTRUNycWRuODhzQ3BSN2ZzMTRm"\ "SzBSaDNaQ1laTEZIcUJrNkFtWlZ3Mks5RkcwTzlyUlBlUURJVlJ5RTMwUXVuUzl1Z0hDNGVnOW92dk9tK1FkWjJwOTNYaHp1blFFaFVXWEN4QURJRUdKSzNT"\ "MmFBZnplOTlQTFMyOWhMY1F1WVhIRGFDN09acU5ub3NpT0dpZnM4djFqaTZIL3hobHRDWmUybEorN0d1dHpleEtweHZwRS90WlNmYlk5MDVxU2xCaDlmcGow"\ "MTVjam5RRmtVc0FVd21LVkFVdWVVejR0S2NGSzRwZXZOTGF4RUFsK09raWxNdElZRGFjRDVuZWw0eEppeXM0MTNoYWdxVzBXaGg1RlAzOWhHazlFL0J3UVRq"\ "YXpTeEdkdlgwbTZ4RlloaC8yVk15WmpUNEt6UEpFQ0F3RUFBYU9DQWxnd2dnSlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUtCZ2dyQmdF"\ "RkJRY0RBVEFNQmdOVkhSTUJBZjhFQWpBQU1CMEdBMVVkRGdRV0JCUXFCUXdHV29KQmExb1RLcXVwbzRXNnhUNmoyREFmQmdOVkhTTUVHREFXZ0JTWTBmaHVF"\ "T3ZQbSt4Z254aVFHNkRyZlFuOUt6QmtCZ2dyQmdFRkJRY0JBUVJZTUZZd0p3WUlLd1lCQlFVSE1BR0dHMmgwZEhBNkx5OXZZM053TG5CcmFTNW5iMjluTDJk"\ "MGN6RnZNVEFyQmdnckJnRUZCUWN3QW9ZZmFIUjBjRG92TDNCcmFTNW5iMjluTDJkemNqSXZSMVJUTVU4eExtTnlkREFkQmdOVkhSRUVGakFVZ2hKaGRIUmxj"\ "M1F1WVc1a2NtOXBaQzVqYjIwd0lRWURWUjBnQkJvd0dEQUlCZ1puZ1F3QkFnSXdEQVlLS3dZQkJBSFdlUUlGQXpBdkJnTlZIUjhFS0RBbU1DU2dJcUFnaGg1"\ "b2RIUndPaTh2WTNKc0xuQnJhUzVuYjI5bkwwZFVVekZQTVM1amNtd3dnZ0VFQmdvckJnRUVBZFo1QWdRQ0JJSDFCSUh5QVBBQWR3Q2t1UW1RdEJoWUZJZTdF"\ "NkxNWjNBS1BEV1lCUGtiMzdqamQ4ME95QTNjRUFBQUFXWmREM1BMQUFBRUF3QklNRVlDSVFDU1pDV2VMSnZzaVZXNkNnK2dqLzl3WVRKUnp1NEhpcWU0ZVk0"\ "Yy9teXpqZ0loQUxTYmkvVGh6Y3pxdGlqM2RrM3ZiTGNJVzNMbDJCMG83NUdRZGhNaWdiQmdBSFVBVmhRR21pL1h3dXpUOWVHOVJMSSt4MFoydWJ5WkVWekE3"\ "NVNZVmRhSjBOMEFBQUZtWFE5ejVBQUFCQU1BUmpCRUFpQmNDd0E5ajdOVEdYUDI3OHo0aHIvdUNIaUFGTHlvQ3EySzAreUxSd0pVYmdJZ2Y4Z0hqdnB3Mm1C"\ "MUVTanEyT2YzQTBBRUF3Q2tuQ2FFS0ZVeVo3Zi9RdEl3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUk5blRmUktJV2d0bFdsM3dCTDU1RVRWNmthenNwaFcx"\ "eUFjNUR1bTZYTzQxa1p6d0o2MXdKbWRSUlQvVXNDSXkxS0V0MmMwRWpnbG5KQ0YyZWF3Y0VXbExRWTJYUEx5RmprV1FOYlNoQjFpNFcyTlJHelBodDNtMWI0"\ "OWhic3R1WE02dFg1Q3lFSG5UaDhCb200L1dsRmloemhnbjgxRGxkb2d6L0syVXdNNlM2Q0IvU0V4a2lWZnYremJKMHJqdmc5NEFsZGpVZlV3a0k5Vk5NakVQ"\ "NWU4eWRCM29MbDZnbHBDZUY1ZGdmU1g0VTl4MzVvai9JSWQzVUUvZFBwYi9xZ0d2c2tmZGV6dG1VdGUvS1Ntcml3Y2dVV1dlWGZUYkkzenNpa3daYmtwbVJZ"\ "S21qUG1odjRybGl6R0NHdDhQbjhwcThNMktEZi9QM2tWb3QzZTE4UT0iLCJNSUlFU2pDQ0F6S2dBd0lCQWdJTkFlTzBtcUdOaXFtQkpXbFF1REFOQmdrcWhr"\ "aUc5dzBCQVFzRkFEQk1NU0F3SGdZRFZRUUxFeGRIYkc5aVlXeFRhV2R1SUZKdmIzUWdRMEVnTFNCU01qRVRNQkVHQTFVRUNoTUtSMnh2WW1Gc1UybG5iakVU"\ "TUJFR0ExVUVBeE1LUjJ4dlltRnNVMmxuYmpBZUZ3MHhOekEyTVRVd01EQXdOREphRncweU1URXlNVFV3TURBd05ESmFNRUl4Q3pBSkJnTlZCQVlUQWxWVE1S"\ "NHdIQVlEVlFRS0V4VkhiMjluYkdVZ1ZISjFjM1FnVTJWeWRtbGpaWE14RXpBUkJnTlZCQU1UQ2tkVVV5QkRRU0F4VHpFd2dnRWlNQTBHQ1NxR1NJYjNEUUVC"\ "QVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURRR005RjFJdk4wNXprUU85K3ROMXBJUnZKenp5T1RIVzVEekVaaEQyZVBDbnZVQTBRazI4RmdJQ2ZLcUM5RWtzQzRU"\ "MmZXQllrL2pDZkMzUjNWWk1kUy9kTjRaS0NFUFpSckF6RHNpS1VEelJybUJCSjV3dWRnem5kSU1ZY0xlL1JHR0ZsNXlPRElLZ2pFdi9TSkgvVUwrZEVhbHRO"\ "MTFCbXNLK2VRbU1GKytBY3hHTmhyNTlxTS85aWw3MUkyZE44RkdmY2Rkd3VhZWo0YlhocDBMY1FCYmp4TWNJN0pQMGFNM1Q0SStEc2F4bUtGc2JqemFUTkM5"\ "dXpwRmxnT0lnN3JSMjV4b3luVXh2OHZObWtxN3pkUEdIWGt4V1k3b0c5aitKa1J5QkFCazdYckpmb3VjQlpFcUZKSlNQazdYQTBMS1cwWTN6NW96MkQwYzF0"\ "Skt3SEFnTUJBQUdqZ2dFek1JSUJMekFPQmdOVkhROEJBZjhFQkFNQ0FZWXdIUVlEVlIwbEJCWXdGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUJJR0Ex"\ "VWRFd0VCL3dRSU1BWUJBZjhDQVFBd0hRWURWUjBPQkJZRUZKalIrRzRRNjgrYjdHQ2ZHSkFib090OUNmMHJNQjhHQTFVZEl3UVlNQmFBRkp2aUIxZG5IQjdB"\ "YWdiZVdiU2FMZC9jR1lZdU1EVUdDQ3NHQVFVRkJ3RUJCQ2t3SnpBbEJnZ3JCZ0VGQlFjd0FZWVphSFIwY0RvdkwyOWpjM0F1Y0d0cExtZHZiMmN2WjNOeU1q"\ "QXlCZ05WSFI4RUt6QXBNQ2VnSmFBamhpRm9kSFJ3T2k4dlkzSnNMbkJyYVM1bmIyOW5MMmR6Y2pJdlozTnlNaTVqY213d1B3WURWUjBnQkRnd05qQTBCZ1pu"\ "Z1F3QkFnSXdLakFvQmdnckJnRUZCUWNDQVJZY2FIUjBjSE02THk5d2Eya3VaMjl2Wnk5eVpYQnZjMmwwYjNKNUx6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FR"\ "RUFHb0ErTm5uNzh5NnBSamQ5WGxRV05hN0hUZ2laL3IzUk5Ha21VbVlIUFFxNlNjdGk5UEVhanZ3UlQyaVdUSFFyMDJmZXNxT3FCWTJFVFV3Z1pRK2xsdG9O"\ "RnZoc085dHZCQ09JYXpwc3dXQzlhSjl4anU0dFdEUUg4TlZVNllaWi9YdGVEU0dVOVl6SnFQalk4cTNNRHhyem1xZXBCQ2Y1bzhtdy93SjRhMkc2eHpVcjZG"\ "YjZUOE1jRE8yMlBMUkw2dTNNNFR6czNBMk0xajZieWtKWWk4d1dJUmRBdktMV1p1L2F4QlZielltcW13a201ekxTRFc1bklBSmJFTENRQ1p3TUg1NnQyRHZx"\ "b2Z4czZCQmNDRklaVVNweHU2eDZ0ZDBWN1N2SkNDb3NpclNtSWF0ai85ZFNTVkRRaWJldDhxLzdVSzR2NFpVTjgwYXRuWnoxeWc9PSJdfQ."\ "eyJub25jZSI6IlhQQjdWVGRSWGJEM01mMENvTFF5ZVJQclA5ZjIzYW9mVHBtVWd6cmlrbzA9IiwidGltZXN0YW1wTXMiOjE1NDA2NTE2ODQwOTMsImFwa1Bh"\ "Y2thZ2VOYW1lIjoiY29tLmdvb2dsZS5hbmRyb2lkLmdtcyIsImFwa0RpZ2VzdFNoYTI1NiI6ImVRYyt2elVjZHgwRlZOTHZYSHVHcEQwK1I4MDdzVUV2cCtK"\ "ZWxlWVpzaUE9IiwiY3RzUHJvZmlsZU1hdGNoIjp0cnVlLCJhcGtDZXJ0aWZpY2F0ZURpZ2VzdFNoYTI1NiI6WyI4UDFzVzBFUEpjc2x3N1V6UnNpWEw2NHcr"\ "TzUwRWQrUkJJQ3RheTFnMjRNPSJdLCJiYXNpY0ludGVncml0eSI6dHJ1ZX0."\ "emYayEmcZR5nGyQ0yayZIwSa8zDC4zCWdzvh9seR3hXYBcmV9lL6PmWp-H58FMnuEahH2HgMAyHo0xPjB0xr1QzFzsbNmEsC-_LotaviM3VIuWahejkx_Rob"\ "-0q3vhCqCYyraMiTcFkzN-bXgauBO0Md9eAGFBR5P0pLnui8_6hpo6wRNA74lGKAs0kOi4A9jUs7Na-A4OaeyYs8Q3q425S7fu6Pzadk4rkZclfEvPIjMqFF"\ "CCO-_llXvHTap4S09_W6tFpR_cw9JXL7g5dUcca5iWoDZxXztsKRz3p1cA1M2gkZsmMWCYD6Kv4BIsHtiitwhL2SNC8QZiYc1Wxj3A" #define TOKEN_WITH_JWK_IN_HEADER "eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR"\ "0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JEQSIsImNydiI"\ "6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIi"\ "wiaWF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg" const unsigned char symmetric_key[] = "my-very-secret"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; const unsigned char rsa_2048_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\n" "iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\n" "lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\n" "Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\n" "TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\n" "45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\n" "2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\n" "n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\n" "wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\n" "z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\n" "3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\n" "UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\n" "DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\n" "DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\n" "m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\n" "cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\n" "1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\n" "I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\n" "INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\n" "vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\n" "Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\n" "TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\n" "+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\n" "mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\n" "LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\n" "tEOtzsP5GMDYVlEp1jYSjzQ=\n" "-----END PRIVATE KEY-----\n"; #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" #define CLAIM_STR "grut" #define CLAIM_INT 42 unsigned char cypher_key[] = {4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}; unsigned char iv[] = {3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}; const unsigned char advanced_key_1[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIAYMcQvkJcMXw5WYHEL05zOvksZ3JG6WAVc4PqupNxncoAoGCCqGSM49\n" "AwEHoUQDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5\n" "plYuZz2/TzJbrwPDUYCB/rV8/hHku0tXnA==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_1[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu\n" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg\n" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG\n" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1\n" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF\n" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1\n" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd\n" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2\n" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU\n" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv\n" "s3yOHp3+WqTOfToYSrrNz2rP\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_1[] = "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv" "s3yOHp3+WqTOfToYSrrNz2rP"; const unsigned char advanced_key_2[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEICXdcvJ68jTD5qOxv5a1QQLE7K6OcqSOjgNLd3pPE1z1oAoGCCqGSM49\n" "AwEHoUQDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3\n" "n5/ijLyQ54f6bWnLkxeuZxRfTdrDHNodOg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_2[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i\n" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE\n" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y\n" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A\n" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A\n" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP\n" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J\n" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy\n" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV\n" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE\n" "TrY5XLCqtITFRVTMubJPyDnc\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_2[] = "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE" "TrY5XLCqtITFRVTMubJPyDnc"; const unsigned char advanced_key_3[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIEslWGWIe3xz8KResadYE+JZEfrPNp4wV7b19He998GLoAoGCCqGSM49\n" "AwEHoUQDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABU\n" "Xm1qDJIFMq/Ct9//ZMw3cHcvzJSDsqOuLQ==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_3[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUF6BNJxZDAJ79e+0I4OStbeBHNB4wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5NDBaFw0yMjA4MjkyMTQ5NDBaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABUXm1q\n" "DJIFMq/Ct9//ZMw3cHcvzJSDsqOuLaN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdgOkpqrAK\n" "R71zgTVIPfKcF40SAzAfBgNVHSMEGDAWgBREM51ULZjY5niamwAnB62dRTAjZDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHe+d5uxOBNW+6o9gyn+g2Q1x0YFJhaCvvgoVVC71\n" "E1WkdBMO0nRYJZNxmNgd13DNvrD+Y31IFmTgGidg9urDq6HLo9Q9UkpAYdOKTsXk\n" "NDo1QL5Kjqspuf2Aco3cDcvR2a5OUAJigftpdjOSTvG3geltDsYcd/khY0dMOl3h\n" "25OZm6KyZAORWw3LhXxtmDfPxe31cd/lEp19Gp8aokLorHc7/yYS5h4OhL146vm/\n" "CHYSt8pAIP65IyKoHJpHdSc4uOz0HJ92lpR10Qa9wqrFzDVcHGDX/JBvS0/H5Uyd\n" "OY4jO7FEImq434YOtSy0yGJh/soK8RNe0frGzoQsQ/WxMBeHnprp/eBVZ8jqvYJ4\n" "GW8kTtl8SGitehjoFdby46nAzdt3dBUcmZhm9Yka4jRVN5mwd+s13Pu2zRSvEwvq\n" "IiKlSjZYotFffUsrfHVYqlk58PX5j7P/fohvLnHkucbu9FVrvVLlqZHK3vzafdw6\n" "SlefNWD4/90X/5VFOpePkjZY\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_3[] = "MIIDDjCCAXagAwIBAgIUcqJBzjg4lb0vBeFBGZ2uuY9ZoLkwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzlaFw0yMjA4MjkyMTQ5MzlaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAE/TPAuX0MdUL6H1xse1VwixvR6wxmy6+GS5XS4P8H6lcczryuu+8Oqz2h" "6sw1ChDIRt00l25j92h1SjFknnbE2qN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBScRf4VnU2d" "71JxFeUmXa5uqaMclTAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAmhXg8uHQcAttx1gOKrLi77q1RpeGIu4dYy0UtOW1" "ucNJuOGs8prcPROPElZEkZmfcgwDd2wwjNfs8tqPrcgSDyipLG7yMEj3uxxSZW7S" "DN72f3qL2QavZ4joVZI5v2VplBFbCqC3Fr06Pg8xRcihfb+SnsrhQ4hVuG6GxIF+" "n/khTXsEW6kEi6V0s79AIFBzYa/nH3sfK4gWQvcmUoBJ3Hzz2EIroB9v+P8OdJcR" "37pfw+IDZx2Ri/W18nLwDTF0NVydT2ZGxHRFjankV2uM5q79nW1fsRCTrfoKxWGN" "pKG9IxeXORwv87pETRxQA8W08AGqBsk62f5/lEuxfJqIw6wZKLtb2nqN912QDXLc" "q0F6StYQHYB7WMZM2FA3AzaYeCjfI5a1/LirKm8okt96HXVo2rpqaDB3sJq5C5u+" "yUZ3i+PlDEkUv3CTYSVYaBjKBDTgj6Z4kxKTdBE/A5rXRwIi14LyddTcPRKDrHlh" "MQJL7ADzfeTbVYOHJx8XEE0F"; const unsigned char advanced_key_4[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIF+8UMnI9we1opth9BXqoNmsyj7bpeyMl6gnj8y4jejaoAoGCCqGSM49\n" "AwEHoUQDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6\n" "KeiN/+ym/O780uZLwqCaFR9ix5I3/Jxpdg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_4[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN\n" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho\n" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA\n" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw\n" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw\n" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a\n" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8\n" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ\n" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N\n" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa\n" "Cggnp64OVIyU5OqLa4BVmWQl\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_4[] = "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa" "Cggnp64OVIyU5OqLa4BVmWQl"; const char advanced_jku_4[] = "{\"keys\":[{\"kty\":\"EC\",\"x\":\"rXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLc\",\"y\":\"Rf9u09u0einojf_spvzu_NLmS8KgmhUfYseSN_ycaXY\",\"crv\":\"P-256\",\"kid\":\"OsipzlLJ1CAOU_WnT2zuB4u31IlgFPsZfT4j4r5qZUA\"}]}"; #define ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY "eyJraWQiOiJkZjVTckx2SlgzWEI3OHhHa25QZVZDemdXOTZhT2pYSTlfQnFtYkUzV0ljIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRVMyNTYifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.xMIMfxFu8_2dp5YLMz-gQc-oG6zjHoiKrkePotwOcnb6kLYJJSzz_Si_5U6y2WvJTIVffy_xd1u8HTk3na3iZg" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_1 "eyJraWQiOiIxIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRVMyNTYifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.lDlF2fw7UMheHG6nGm6Deu8O5jv35kxzZI1ToEccEuxWAkNBs1YFYCzriqp-dlrDQfz0LBPnty0O1TwpPbhUpg" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_2 "eyJraWQiOiJuZTQ1Sk9WVXFCOGFwelhPbU9fdDY1ekwtU0dkOUtuTVdfT0NtOUNUZUJRIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRVMyNTYifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.U-T6xY5_TX72xzTEFaQnNQPeJXctJobcU4GCIZ002s50q7VtgCZXIbWVvqVHHY3Gdz551q0Ulvg4_Hx7smv20g" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_3 "eyJraWQiOiJkZjVTckx2SlgzWEI3OHhHa25QZVZDemdXOTZhT2pYSTlfQnFtYkUzV0ljIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRVMyNTYifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.2k55DjC_1Ug0uPtOncD93OmE4aVdi0QFFjJCnfR6LSwzxjBnMFw0Kt88tqnJ0aExwpkJKgGEKyaf1aB0sEW2PA" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_4 "eyJraWQiOiJPc2lwemxMSjFDQU9VX1duVDJ6dUI0dTMxSWxnRlBzWmZUNGo0cjVxWlVBIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwiYWxnIjoiRVMyNTYifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.01ys5UB-MhkIh4YEbSJ-RTvWjBx8ujicO8MV40SHWnXJNcBht-6uyP_CQH7h8qmgxfOpEVaznAcYgH7OhBxtLQ" START_TEST(test_rhonabwy_init) { jws_t * jws; ck_assert_int_eq(r_jws_init(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_payload) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(NULL, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, 0), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, NULL, o_strlen(PAYLOAD)), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_alg) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_UNKNOWN); ck_assert_int_eq(r_jws_set_alg(NULL, R_JWA_ALG_ES256), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_ES256), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_ES256); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS512), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_RS512); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_header) { jws_t * jws; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_header_str_value(NULL, "key", "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_str_value(jws, NULL, "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", NULL), RHN_OK); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", "value"), RHN_OK); ck_assert_int_eq(r_jws_set_header_int_value(NULL, "key", 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_int_value(jws, NULL, 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_int_value(jws, "key", 42), RHN_OK); ck_assert_int_eq(r_jws_set_header_json_t_value(NULL, "key", j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, NULL, j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "key", NULL), RHN_OK); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "key", j_value), RHN_OK); json_decref(j_value); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_get_header) { jws_t * jws; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_header_str_value(jws, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jws_set_header_int_value(jws, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "keyjson", j_value), RHN_OK); ck_assert_str_eq("value", r_jws_get_header_str_value(jws, "keystr")); ck_assert_int_eq(42, r_jws_get_header_int_value(jws, "keyint")); ck_assert_int_eq(json_equal(j_value, (j_result = r_jws_get_header_json_t_value(jws, "keyjson"))) , 1); ck_assert_ptr_eq(NULL, r_jws_get_header_str_value(jws, "error")); ck_assert_int_eq(0, r_jws_get_header_int_value(jws, "error")); ck_assert_ptr_eq(NULL, r_jws_get_header_json_t_value(jws, "error")); json_decref(j_value); json_decref(j_result); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_full_header_error) { jws_t * jws; json_t * j_header; j_header = json_pack("{ss}", "alg", "error"); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_full_header_json_t(jws, j_header), RHN_ERROR_PARAM); r_jws_free(jws); json_decref(j_header); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_full_header_json_t(jws, NULL), RHN_ERROR_PARAM); r_jws_free(jws); j_header = json_pack("{ss}", "alg", r_jwa_alg_to_str(R_JWA_ALG_RS256)); ck_assert_int_eq(r_jws_set_full_header_json_t(NULL, j_header), RHN_ERROR_PARAM); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_set_full_header) { jws_t * jws; json_t * j_header = json_pack("{sssisoss}", "str", CLAIM_STR, "int", CLAIM_INT, "obj", json_true(), "alg", r_jwa_alg_to_str(R_JWA_ALG_RS256)); char * str_header = json_dumps(j_header, JSON_COMPACT); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_full_header_json_t(jws, j_header), RHN_OK); ck_assert_str_eq(r_jws_get_header_str_value(jws, "str"), CLAIM_STR); ck_assert_int_eq(r_jws_get_header_int_value(jws, "int"), CLAIM_INT); ck_assert_ptr_eq(r_jws_get_header_json_t_value(jws, "obj"), json_true()); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_RS256); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_full_header_json_str(jws, str_header), RHN_OK); ck_assert_str_eq(r_jws_get_header_str_value(jws, "str"), CLAIM_STR); ck_assert_int_eq(r_jws_get_header_int_value(jws, "int"), CLAIM_INT); ck_assert_ptr_eq(r_jws_get_header_json_t_value(jws, "obj"), json_true()); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_RS256); r_jws_free(jws); o_free(str_header); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_get_full_header) { jws_t * jws; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_header = json_pack("{sssssisO}", "alg", "RS256", "keystr", "value", "keyint", 42, "keyjson", j_value), * j_result; ck_assert_ptr_ne(j_header, NULL); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_header_str_value(jws, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jws_set_header_int_value(jws, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "keyjson", j_value), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(json_equal(j_header, (j_result = r_jws_get_full_header_json_t(jws))) , 1); json_decref(j_value); json_decref(j_header); json_decref(j_result); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_keys) { jws_t * jws; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa, * jwk_key_symmetric; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_pubkey_rsa, jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_int_eq(r_jws_add_keys(NULL, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_add_keys(jws, NULL, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_key_symmetric); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_jwks) { jws_t * jws; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; jwks_t * jwks_pubkey, * jwks_privkey, * jwks; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_rsa), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(0, r_jwks_size(jws->jwks_privkey)); ck_assert_int_eq(0, r_jwks_size(jws->jwks_pubkey)); ck_assert_int_eq(r_jws_add_jwks(jws, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_int_eq(2, r_jwks_size(jws->jwks_privkey)); ck_assert_int_eq(2, r_jwks_size(jws->jwks_pubkey)); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_add_keys_by_content) { jws_t * jws; jwk_t * jwk_priv, * jwk_pub; jwks_t * jwks; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t g_privkey; gnutls_pubkey_t g_pubkey; #endif json_t * j_privkey, * j_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_rsa_str), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(g_privkey = r_jwk_export_to_gnutls_privkey(jwk_priv), NULL); ck_assert_ptr_ne(g_pubkey = r_jwk_export_to_gnutls_pubkey(jwk_pub, 0), NULL); #endif ck_assert_ptr_ne(j_privkey = r_jwk_export_to_json_t(jwk_priv), NULL); ck_assert_ptr_ne(j_pubkey = r_jwk_export_to_json_t(jwk_pub), NULL); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jws_add_keys_json_str(jws, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jws_add_keys_json_t(jws, j_privkey, j_pubkey), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jws_add_keys_pem_der(jws, R_FORMAT_PEM, rsa_2048_priv, sizeof(rsa_2048_priv), rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jws_add_key_symmetric(jws, symmetric_key, sizeof(symmetric_key)), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jws_add_keys_gnutls(jws, g_privkey, g_pubkey), RHN_OK); jwks = r_jws_get_jwks_privkey(jws); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jws_get_jwks_pubkey(jws); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); #endif r_jws_free(jws); #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_deinit(g_privkey); gnutls_pubkey_deinit(g_pubkey); #endif json_decref(j_privkey); json_decref(j_pubkey); r_jwk_free(jwk_priv); r_jwk_free(jwk_pub); } END_TEST START_TEST(test_rhonabwy_parse) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_UNSECURE, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_EMPTY_HEADER, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_EMPTY_PAYLOAD, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_UNSECURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_android_safetynet_jwt) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ANDROID_SAFETYNET_JWT, 0), RHN_OK); ck_assert_int_gt(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ANDROID_SAFETYNET_JWT, R_PARSE_HEADER_X5C, 0), RHN_OK); ck_assert_int_gt(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ANDROID_SAFETYNET_JWT, R_PARSE_NONE, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_token_unsecure) { jws_t * jws_sign, * jws_verify; char * token; ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_NONE), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize_unsecure(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse_unsecure(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, NULL, 0), RHN_ERROR_INVALID); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); } END_TEST START_TEST(test_rhonabwy_token_parse_unsecure) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, UNSECURE_TOKEN, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_parse_unsecure(jws, UNSECURE_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_NONE); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_HS256); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_unsecure(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_HS256); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_token_serialize_unsecure) { jws_t * jws; jwk_t * jwk_privkey; char * token; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize_unsecure(jws, jwk_privkey, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_NONE), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize_unsecure(jws, NULL, 0)), NULL); o_free(token); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_copy) { jws_t * jws, * jws_copy; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL, * token_copy; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); ck_assert_ptr_ne((jws_copy = r_jws_copy(jws)), NULL); ck_assert_ptr_ne((token_copy = r_jws_serialize(jws_copy, NULL, 0)), NULL); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_str_eq(token, token_copy); #endif o_free(token); o_free(token_copy); r_jws_free(jws); r_jws_free(jws_copy); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_set_properties_error) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_FULL_JSON_STR, json_true(), RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_FULL_JSON_STR, "{}", RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_INT_VALUE, "key", CLAIM_INT, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_INT_VALUE, "key", CLAIM_INT, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_JSON_T_VALUE, "key", json_true(), RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CLAIM_STR_VALUE, "key", CLAIM_STR, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_ENC_ALG, R_JWA_ALG_RSA1_5, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_ENC, R_JWA_ENC_A256GCM, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_ENCRYPT_KEY_JWK, jwk, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_DECRYPT_KEY_JWK, jwk, RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_CIPHER_KEY, cypher_key, sizeof(cypher_key), RHN_OPT_NONE), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_IV, iv, sizeof(iv), RHN_OPT_NONE), RHN_ERROR_PARAM); r_jws_free(jws); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_set_properties) { jws_t * jws; jwk_t * jwk; const unsigned char * key_iv; size_t key_iv_len; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_properties(jws, RHN_OPT_HEADER_INT_VALUE, "int", CLAIM_INT, RHN_OPT_HEADER_RHN_INT_VALUE, "rhn_int", (rhn_int_t)CLAIM_INT, RHN_OPT_HEADER_STR_VALUE, "str", CLAIM_STR, RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_PAYLOAD, PAYLOAD, o_strlen(PAYLOAD), RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_SIGN_KEY_JWK, jwk, RHN_OPT_VERIFY_KEY_JWK, jwk, RHN_OPT_NONE), RHN_OK); ck_assert_int_eq(CLAIM_INT, r_jws_get_header_int_value(jws, "int")); ck_assert_int_eq(CLAIM_INT, r_jws_get_header_int_value(jws, "rhn_int")); ck_assert_str_eq(CLAIM_STR, r_jws_get_header_str_value(jws, "str")); ck_assert_ptr_eq(json_true(), r_jws_get_header_json_t_value(jws, "json")); ck_assert_ptr_ne(NULL, key_iv = r_jws_get_payload(jws, &key_iv_len)); ck_assert_int_eq(o_strlen(PAYLOAD), key_iv_len); ck_assert_int_eq(0, memcmp(key_iv, PAYLOAD, key_iv_len)); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(1, r_jwks_size(jws->jwks_privkey)); ck_assert_int_eq(1, r_jwks_size(jws->jwks_pubkey)); r_jws_free(jws); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_zip_payload) { jws_t * jws, * jws_parse, * jws_parse_def; jwk_t * jwk_key_symmetric; char * token = NULL, * token_def = NULL; const unsigned char * payload, * payload_def; size_t payload_len = 0, payload_def_len = 0; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)HUGE_PAYLOAD, o_strlen(HUGE_PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); ck_assert_int_eq(r_jws_set_header_str_value(jws, "zip", "DEF"), RHN_OK); ck_assert_ptr_ne((token_def = r_jws_serialize(jws, NULL, 0)), NULL); ck_assert_int_gt(o_strlen(token), o_strlen(token_def)); ck_assert_int_eq(r_jws_init(&jws_parse), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_parse_def), RHN_OK); ck_assert_int_eq(r_jws_parse(jws_parse, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_parse, jwk_key_symmetric, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jws_get_payload(jws_parse, &payload_len)); ck_assert_int_eq(r_jws_parse(jws_parse_def, token_def, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_parse_def, jwk_key_symmetric, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload_def = r_jws_get_payload(jws_parse_def, &payload_def_len)); ck_assert_int_eq(payload_len, payload_def_len); ck_assert_int_eq(0, memcmp(payload, payload_def, payload_def_len)); r_jws_free(jws_parse); r_jws_free(jws_parse_def); o_free(token); o_free(token_def); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST #if GNUTLS_VERSION_NUMBER >= 0x030600 START_TEST(test_rhonabwy_jwk_in_header) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, TOKEN_WITH_JWK_IN_HEADER, 0), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_gt(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_jwk_in_header_invalid) { jws_t * jws, * jws_parsed; jwk_t * jwk; json_t * j_jwk; char * str_jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_parsed), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne(NULL, j_jwk = json_loads(jwk_privkey_ecdsa_str, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "jwk", j_jwk), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_ES256), RHN_OK); ck_assert_ptr_ne(NULL, str_jws = r_jws_serialize(jws, jwk, 0)); ck_assert_int_eq(r_jws_parse(jws_parsed, str_jws, 0), RHN_ERROR_PARAM); o_free(str_jws); json_decref(j_jwk); ck_assert_ptr_ne(NULL, j_jwk = json_loads(jwk_key_symmetric_str, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "jwk", j_jwk), RHN_OK); ck_assert_ptr_ne(NULL, str_jws = r_jws_serialize(jws, jwk, 0)); ck_assert_int_eq(r_jws_parse(jws_parsed, str_jws, 0), RHN_ERROR_PARAM); o_free(str_jws); json_decref(j_jwk); ck_assert_ptr_ne(NULL, j_jwk = json_pack("{ss}", "error", "this is not a jwk")); ck_assert_ptr_ne(NULL, str_jws = r_jws_serialize(jws, jwk, 0)); ck_assert_int_eq(r_jws_parse(jws_parsed, str_jws, 0), RHN_ERROR_PARAM); o_free(str_jws); ck_assert_int_eq(r_jws_set_header_json_t_value(jws, "jwk", j_jwk), RHN_OK); json_decref(j_jwk); r_jwk_free(jwk); r_jws_free(jws); r_jws_free(jws_parsed); } END_TEST #ifdef R_WITH_CURL static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)advanced_cert_pem_3); return U_CALLBACK_CONTINUE; } int callback_jku_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_response_properties(response, U_OPT_STATUS, 200, U_OPT_HEADER_PARAMETER, "Content-Type", "application/json", U_OPT_STRING_BODY, advanced_jku_4, U_OPT_NONE); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_advanced_parse) { jwk_t * jwk_pub; jws_t * jws; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5U|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 2); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); r_jws_free(jws); // Attack vectors tested ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_HEADER_X5C|R_PARSE_HEADER_X5U|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 3); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5U|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 3); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 3); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C|R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 3); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_advanced_parse(jws, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 1); ck_assert_int_eq(r_jwks_append_jwk(jws->jwks_pubkey, jwk_pub), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pub); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_quick_parse) { jwk_t * jwk_pub; jws_t * jws; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne(NULL, jws = r_jws_quick_parse(HS256_TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); r_jws_free(jws); ck_assert_ptr_eq(NULL, jws = r_jws_quick_parse(HS256_TOKEN_INVALID_DOTS, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jws = r_jws_quick_parse(HS256_TOKEN_INVALID_HEADER, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jws = r_jws_quick_parse(HS256_TOKEN_INVALID_HEADER_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jws = r_jws_quick_parse(HS256_TOKEN_INVALID_PAYLOAD_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jws = r_jws_quick_parse(UNSECURE_TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_ne(NULL, jws = r_jws_quick_parse(UNSECURE_TOKEN, R_PARSE_UNSIGNED, R_FLAG_IGNORE_SERVER_CERTIFICATE)); r_jws_free(jws); ck_assert_ptr_ne(NULL, jws = r_jws_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 0); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); r_jws_free(jws); ck_assert_ptr_ne(NULL, jws = r_jws_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 4); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); r_jws_free(jws); ck_assert_ptr_ne(NULL, jws = r_jws_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jws->jwks_pubkey), 2); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pub, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_pub); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST #endif #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS core function tests"); tc_core = tcase_create("test_rhonabwy_core"); tcase_add_test(tc_core, test_rhonabwy_init); tcase_add_test(tc_core, test_rhonabwy_payload); tcase_add_test(tc_core, test_rhonabwy_alg); tcase_add_test(tc_core, test_rhonabwy_set_header); tcase_add_test(tc_core, test_rhonabwy_get_header); tcase_add_test(tc_core, test_rhonabwy_set_full_header_error); tcase_add_test(tc_core, test_rhonabwy_set_full_header); tcase_add_test(tc_core, test_rhonabwy_get_full_header); tcase_add_test(tc_core, test_rhonabwy_set_keys); tcase_add_test(tc_core, test_rhonabwy_set_jwks); tcase_add_test(tc_core, test_rhonabwy_add_keys_by_content); tcase_add_test(tc_core, test_rhonabwy_parse); tcase_add_test(tc_core, test_rhonabwy_parse_android_safetynet_jwt); tcase_add_test(tc_core, test_rhonabwy_token_unsecure); tcase_add_test(tc_core, test_rhonabwy_token_parse_unsecure); tcase_add_test(tc_core, test_rhonabwy_token_serialize_unsecure); tcase_add_test(tc_core, test_rhonabwy_copy); tcase_add_test(tc_core, test_rhonabwy_set_properties_error); tcase_add_test(tc_core, test_rhonabwy_set_properties); tcase_add_test(tc_core, test_rhonabwy_zip_payload); #if GNUTLS_VERSION_NUMBER >= 0x030600 tcase_add_test(tc_core, test_rhonabwy_jwk_in_header); tcase_add_test(tc_core, test_rhonabwy_jwk_in_header_invalid); #ifdef R_WITH_CURL tcase_add_test(tc_core, test_rhonabwy_advanced_parse); tcase_add_test(tc_core, test_rhonabwy_quick_parse); #endif #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS core tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_ecdsa.c000066400000000000000000000454051452472117100165270ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define ES256_TOKEN "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.8SGjljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_INVALID_HEADER "eyJhbGciOiJFUzI1NiIsImtpZCI6Ij.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.8SGjljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_INVALID_HEADER_B64 ";error;.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.8SGjljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_INVALID_PAYLOAD_B64 "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.;error;.8SGjljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_INVALID_SIGNATURE "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.8S6jljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_INVALID_DOTS "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQVGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.8SGjljD8Zrj9nZRXFbWny8KYLokjvnuFersudKTYCU7LyiOHed81goqaW3J1gDY-8zIjGnT_EV2YZsT7GVyBjQ" #define ES256_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." #define E25519_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJFZERTQSJ9.RXhhbXBsZSBvZiBFZDI1NTE5IHNpZ25pbmc." const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; const char jwk_pubkey_ecdsa_no_alg_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_no_alg_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str_2[] = "{\"kty\":\"EC\",\"x\":\"RKL0w34ppc4wuBuzotuWo9d6hGv59uWjgc5oimWQtYU\",\"y\":\"S8EabLKBmyT2v_vPSrpfWnYw6edRm9I60UQlbvSS1eU\""\ ",\"d\":\"KMRJaGpxVer0w9lMjIY_UrjC067tZdEJkL5eaiBVWi8\",\"crv\":\"P-256\",\"kid\":\"2\",\"alg\":\"ES256\"}"; const char jwk_privkey_ecdsa_str_2[] = "{\"kty\":\"EC\",\"x\":\"RKL0w34ppc4wuBuzotuWo9d6hGv59uWjgc5oimWQtYU\",\"y\":\"S8EabLKBmyT2v_vPSrpfWnYw6edRm9I60UQlbvSS1eU\","\ "\"crv\":\"P-256\",\"kid\":\"2\",\"alg\":\"ES256\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0Cg\",\"kid\":\"1\"}"; const char jwk_pubkey_eddsa_str[] = "{\"kty\":\"OKP\",\"x\":\"vG-37qz4ywqzukNS-jMAfXSSA7V28y0vv9RxlibxgPw\","\ "\"crv\":\"Ed25519\",\"kid\":\"3\"}"; const char jwk_privkey_eddsa_str[] = "{\"kty\":\"OKP\",\"x\":\"vG-37qz4ywqzukNS-jMAfXSSA7V28y0vv9RxlibxgPw\","\ "\"d\":\"DGw7wgt65TPJAxEjuUmCjTjmafg4mKUPj3S3iAVoTYQ\",\"crv\":\"Ed25519\",\"kid\":\"3\"}"; #if GNUTLS_VERSION_NUMBER >= 0x030600 START_TEST(test_rhonabwy_serialize_error_header) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); ck_assert_ptr_eq(r_jws_serialize(NULL, jwk_privkey, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_error_payload) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_ES256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_ES256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_no_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_with_key_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_ES256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, jwk_privkey, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", "value"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, jwk_privkey, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key2", "value2"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, jwk_privkey, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid_content) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, "error", 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_token) { jws_t * jws; size_t payload_len = 0; const unsigned char * payload = NULL; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_ptr_ne((payload = r_jws_get_payload(jws, &payload_len)), NULL); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_gt(payload_len, 0); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)payload, payload_len)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str_2), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, E25519_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(R_JWA_ALG_EDDSA, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_eddsa_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_key_type) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_kid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); r_jwk_set_property_str(jwk_pubkey, "kid", "42"); r_jws_add_keys(jws, NULL, jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_multiple_keys_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, ES256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str_2), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_ES256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_ES384), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_ES512), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_eddsa_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_eddsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_eddsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_EDDSA), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST #if 0 START_TEST(test_rhonabwy_es256k_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_ES256K), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST #endif #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS ECDSA function tests"); tc_core = tcase_create("test_rhonabwy_ecdsa"); #if GNUTLS_VERSION_NUMBER >= 0x030600 tcase_add_test(tc_core, test_rhonabwy_serialize_error_header); tcase_add_test(tc_core, test_rhonabwy_serialize_error_payload); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_no_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_serialize_with_key_ok); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid_content); tcase_add_test(tc_core, test_rhonabwy_parse_token); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_key_type); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_kid); tcase_add_test(tc_core, test_rhonabwy_verify_token_valid); tcase_add_test(tc_core, test_rhonabwy_verify_token_multiple_keys_valid); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_verify_ok); tcase_add_test(tc_core, test_rhonabwy_eddsa_serialize_verify_ok); #if 0 tcase_add_test(tc_core, test_rhonabwy_es256k_serialize_verify_ok); #endif #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS ECDSA tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_hmac.c000066400000000000000000000326641452472117100163630ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define HS256_TOKEN "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_INVALID_HEADER "eyJhbGciOiJIUzI1NiIsImtpZCI6Ij.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_INVALID_HEADER_B64 ";error;.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_INVALID_PAYLOAD_B64 "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.;error;.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_INVALID_SIGNATURE "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-5X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_INVALID_DOTS "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQVGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GKxWqRBFr-6X4HfflzGeGvKVsJ8v1-J39Ho2RslC-5o" #define HS256_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJIUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0\",\"kid\":\"1\"}"; const char jwk_key_symmetric_str_2[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"dGVyY2Vz\",\"kid\":\"2\"}"; const char jwk_key_symmetric_no_alg_str[] = "{\"kty\":\"oct\",\"k\":\"c2VjcmV0\",\"kid\":\"1\"}"; const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\",\"alg\":\"ES256\"}"; START_TEST(test_rhonabwy_serialize_error_header) { jws_t * jws; jwk_t * jwk_key_symmetric; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); ck_assert_ptr_eq(r_jws_serialize(NULL, jwk_key_symmetric, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_serialize_error_payload) { jws_t * jws; jwk_t * jwk_key_symmetric; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_HS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_key_symmetric; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_HS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_no_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_key_symmetric; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_serialize_with_key_ok) { jws_t * jws; jwk_t * jwk_key_symmetric; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_key_symmetric, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", "value"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key2", "value2"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid_content) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, "error", 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_token) { jws_t * jws; size_t payload_len = 0; const unsigned char * payload = NULL; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_ptr_ne((payload = r_jws_get_payload(jws, &payload_len)), NULL); ck_assert_int_eq(R_JWA_ALG_HS256, r_jws_get_alg(jws)); ck_assert_int_gt(payload_len, 0); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)payload, payload_len)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid) { jws_t * jws; jwk_t * jwk_key_symmetric; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_key_symmetric, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_key_symmetric, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str_2), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_key_symmetric, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_key_type) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_kid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_HS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_key_symmetric_str), RHN_OK); r_jwk_set_property_str(jwk_pubkey, "kid", "42"); r_jws_add_keys(jws, NULL, jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_valid) { jws_t * jws; jwk_t * jwk_key_symmetric; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_key_symmetric, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_key_symmetric, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_key_symmetric); } END_TEST START_TEST(test_rhonabwy_verify_token_multiple_keys_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, HS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_HS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_key_symmetric_str_2), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_key_symmetric_str), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_HS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_HS384), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_HS512), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS HMAC function tests"); tc_core = tcase_create("test_rhonabwy_hmac"); tcase_add_test(tc_core, test_rhonabwy_serialize_error_header); tcase_add_test(tc_core, test_rhonabwy_serialize_error_payload); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_no_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_serialize_with_key_ok); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid_content); tcase_add_test(tc_core, test_rhonabwy_parse_token); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_key_type); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_kid); tcase_add_test(tc_core, test_rhonabwy_verify_token_valid); tcase_add_test(tc_core, test_rhonabwy_verify_token_multiple_keys_valid); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_verify_ok); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS HMAC tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_json.c000066400000000000000000001320051452472117100164120ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define KID_1 "Raoul" #define KID_2 "Ernie" #define KID_3 "Sammy" const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\""KID_1"\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\""KID_1"\",\"alg\":\"ES256\"}"; const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"kid\":\""KID_2"\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\""KID_2"\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0Cg\",\"kid\":\""KID_3"\"}"; #define JWS_FLATTENED "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_INVALID_JSON "error\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_MISSING_PAYLOAD "{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_MISSING_PROTECTED "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_INVALID_SIGNATURE "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2NAwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_INVALID_PAYLOAD_B64 "{\"payload\":\"VGhlIHRydWUgc2ln;error;xpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_INVALID_HEADER_B64 "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJh;error;I1NiJ9\",\"signature\":\"V0O2NqwDK3Ovq4ATITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_FLATTENED_INVALID_SIGNATURE_B64 "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"V0O2Nqw;error;TITgR1GRFEQ8nj_SMvcuhIRWUZMJ2thkNm8jivmc0KzF-iE3aaqy_vyPEvS6544Z6LzCpJw\",\"header\":{\"kid\":\""KID_1"\"}}" #define JWS_GENERAL "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_INVALID_JSON "error\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_MISSING_PAYLOAD "{\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_INVALID_SIGNATURE "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKAuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_INVALID_SIGNATURE_NO_KID "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\"},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\"},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKAuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\"}]}" #define JWS_GENERAL_MISSING_PROTECTED "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_MISSING_SIGNATURE "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_INVALID_PAYLOAD_B64 "{\"payload\":\"VGhlIHRydWUgc2ln;error;xpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_INVALID_HEADER_B64 "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJh;error;I1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_SIGNATURE_B64 "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\",\"header\":{\"kid\":\""KID_1"\"}},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\",\"header\":{\"kid\":\""KID_2"\"}},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcw;error;VqS39pNNPC736AaWOyzpTwf0I\",\"header\":{\"kid\":\""KID_3"\"}}]}" #define JWS_GENERAL_MISSING_KID "{\"payload\":\"VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u\",\"signatures\":[{\"protected\":\"eyJhbGciOiJFUzI1NiJ9\",\"signature\":\"M-23B3n2CvCTSOo4QjKuHmchAW0uonm-Tzv99Eb4btt-0CLVU-h_6Kt5mL6OtgIt8YKnUoXQGZcLWUVAcI6HeA\"},{\"protected\":\"eyJhbGciOiJSUzI1NiJ9\",\"signature\":\"rHVAWhXPsq1QYmP9S0R01poEH7d-Y6cN-KUAhFFDQRXqjPeNFL54OrGQKrTCpL_MremwLk3gOLy7L2HlNeawsoD4cLo6_qNDxOQ34S3gB4ti4FW7mFbbiLvwTcZmj88OZoub00Q8mRBWcE1uZOYo3InBNaxNGmK1Bu5l68nFIX04U8-eol_2VlA8Qy6GJ7DTfZEMncn_iBHKSy0Vb19rdFFY2wcrPKYksg8jw4q6i_uGCH0lZ6dY3v0j99AyO2cKPgTDibcTRreYQdYQag1vNrWoVafJkQo8v3sJNtHHjjCfEG6iUQPEJLBBp52o1ID5g8KhwGVuipvwS0_YdlYwnQ\"},{\"protected\":\"eyJhbGciOiJIUzI1NiJ9\",\"signature\":\"GV6JkVcwKSuz2uTOJwVqS39pNNPC736AaWOyzpTwf0I\"}]}" START_TEST(test_rhonabwy_json_no_key) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_eq(NULL, r_jws_serialize_json_t(jws, NULL, 0, R_JSON_MODE_GENERAL)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_no_jws) { jwk_t * jwk; jwks_t * jwks_privkey; ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_ptr_eq(NULL, r_jws_serialize_json_t(NULL, jwks_privkey, 0, R_JSON_MODE_GENERAL)); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_with_jwks_with_missing_kid) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_delete_property_str(jwk, "kid"), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, jwks_privkey, 0, R_JSON_MODE_GENERAL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_eq(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_ptr_eq(NULL, json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header")); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 2), "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_with_jwks_with_missing_alg) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_delete_property_str(jwk, "alg"), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, jwks_privkey, 0, R_JSON_MODE_GENERAL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_gt(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_with_jwks_with_invalid_alg) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_set_property_str(jwk, "alg", "error"), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, jwks_privkey, 0, R_JSON_MODE_GENERAL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_gt(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_with_jwks) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, jwks_privkey, 0, R_JSON_MODE_GENERAL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_eq(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_str_eq(KID_1, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header"), "kid"))); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 2), "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_without_jwks) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_jwks(jws, jwks_privkey, NULL), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_eq(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_str_eq(KID_1, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header"), "kid"))); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 2), "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_general_str) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; char * str_result; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_jwks(jws, jwks_privkey, NULL), RHN_OK); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_ptr_ne(NULL, j_result = json_loads(str_result, JSON_DECODE_ANY, NULL)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_eq(r_jwks_size(jwks_privkey), json_array_size(json_object_get(j_result, "signatures"))); ck_assert_str_eq(KID_1, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 0), "header"), "kid"))); ck_assert_str_eq(KID_2, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 1), "header"), "kid"))); ck_assert_str_eq(KID_3, json_string_value(json_object_get(json_object_get(json_array_get(json_object_get(j_result, "signatures"), 2), "header"), "kid"))); o_free(str_result); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_json_flattened_with_jwks) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey; json_t * j_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_ptr_ne(NULL, j_result = r_jws_serialize_json_t(jws, jwks_privkey, 0, R_JSON_MODE_FLATTENED)); ck_assert_str_eq("VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u", json_string_value(json_object_get(j_result, "payload"))); ck_assert_int_gt(json_string_length(json_object_get(j_result, "signature")), 0); ck_assert_str_eq(KID_1, json_string_value(json_object_get(json_object_get(j_result, "header"), "kid"))); json_decref(j_result); r_jws_free(jws); r_jwks_free(jwks_privkey); } END_TEST START_TEST(test_rhonabwy_parse_json_flattened_error) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_INVALID_JSON, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_MISSING_PAYLOAD, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_MISSING_PROTECTED, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_INVALID_SIGNATURE_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(NULL, JWS_FLATTENED, 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_json_flattened_str) { jws_t * jws; const unsigned char * payload; size_t payload_len; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jws_get_payload(jws, &payload_len)); ck_assert_int_eq(payload_len, o_strlen(PAYLOAD)); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, o_strlen(PAYLOAD))); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_str_eq(KID_1, r_jws_get_kid(jws)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_json_flattened_json_t) { jws_t * jws; const unsigned char * payload; size_t payload_len; json_t * j_jws = json_loads(JWS_FLATTENED, JSON_DECODE_ANY, NULL); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_t(jws, j_jws, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jws_get_payload(jws, &payload_len)); ck_assert_int_eq(payload_len, o_strlen(PAYLOAD)); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, o_strlen(PAYLOAD))); ck_assert_int_eq(R_JWA_ALG_ES256, r_jws_get_alg(jws)); ck_assert_str_eq(KID_1, r_jws_get_kid(jws)); r_jws_free(jws); json_decref(j_jws); } END_TEST START_TEST(test_rhonabwy_json_flattened_verify_signature) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_OK); r_jwk_free(jwk); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_flattened_invalid_signature) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_FLATTENED_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_ERROR_INVALID); r_jwk_free(jwk); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_json_general_error) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_INVALID_JSON, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_MISSING_PAYLOAD, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_MISSING_PROTECTED, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_MISSING_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_SIGNATURE_B64, 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_json_general_str) { jws_t * jws; const unsigned char * payload; size_t payload_len; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jws_get_payload(jws, &payload_len)); ck_assert_int_eq(payload_len, o_strlen(PAYLOAD)); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, o_strlen(PAYLOAD))); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_json_general_t) { jws_t * jws; const unsigned char * payload; size_t payload_len; json_t * j_jws = json_loads(JWS_GENERAL, JSON_DECODE_ANY, NULL); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_t(jws, j_jws, 0), RHN_OK); ck_assert_ptr_ne(NULL, payload = r_jws_get_payload(jws, &payload_len)); ck_assert_int_eq(payload_len, o_strlen(PAYLOAD)); ck_assert_int_eq(0, memcmp(PAYLOAD, payload, o_strlen(PAYLOAD))); r_jws_free(jws); json_decref(j_jws); } END_TEST START_TEST(test_rhonabwy_json_general_verify_signature_with_all_public_jwks) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_str(jws, NULL, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_str(jws, NULL, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_str(jws, NULL, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_general_verify_signature_with_one_public_jwks) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_str(jws, NULL, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_general_verify_signature_with_jwk) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL, 0), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_RS256); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_ES256); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_OK); ck_assert_int_eq(r_jws_get_alg(jws), R_JWA_ALG_HS256); r_jwk_free(jwk); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_general_invalid_signature) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_add_keys_json_str(jws, NULL, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_json_general_verify_signature_with_no_kid) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_MISSING_KID, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_json_general_invalid_signature_with_no_kid) { jws_t * jws; jwk_t * jwk; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, JWS_GENERAL_INVALID_SIGNATURE_NO_KID, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_json_general_flood) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey, * jwks_pubkey; char * str_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_jwks(jws, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_GENERAL)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_GENERAL)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_GENERAL)); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); o_free(str_result); r_jws_free(jws); r_jwks_free(jwks_privkey); r_jwks_free(jwks_pubkey); } END_TEST START_TEST(test_rhonabwy_json_flattened_flood) { jws_t * jws; jwk_t * jwk; jwks_t * jwks_privkey, * jwks_pubkey; char * str_result; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk), RHN_OK); r_jwk_free(jwk); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_jwks(jws, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_FLATTENED)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_FLATTENED)); o_free(str_result); ck_assert_ptr_ne(NULL, str_result = r_jws_serialize_json_str(jws, NULL, 0, R_JSON_MODE_FLATTENED)); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_parse_json_str(jws, str_result, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); o_free(str_result); r_jws_free(jws); r_jwks_free(jwks_privkey); r_jwks_free(jwks_pubkey); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS JSON function tests"); tc_core = tcase_create("test_rhonabwy_json"); tcase_add_test(tc_core, test_rhonabwy_json_no_key); tcase_add_test(tc_core, test_rhonabwy_json_no_jws); tcase_add_test(tc_core, test_rhonabwy_json_general_with_jwks_with_missing_kid); tcase_add_test(tc_core, test_rhonabwy_json_general_with_jwks_with_missing_alg); tcase_add_test(tc_core, test_rhonabwy_json_general_with_jwks_with_invalid_alg); tcase_add_test(tc_core, test_rhonabwy_json_general_with_jwks); tcase_add_test(tc_core, test_rhonabwy_json_general_without_jwks); tcase_add_test(tc_core, test_rhonabwy_json_general_str); tcase_add_test(tc_core, test_rhonabwy_json_flattened_with_jwks); tcase_add_test(tc_core, test_rhonabwy_parse_json_flattened_error); tcase_add_test(tc_core, test_rhonabwy_parse_json_flattened_str); tcase_add_test(tc_core, test_rhonabwy_parse_json_flattened_json_t); tcase_add_test(tc_core, test_rhonabwy_json_flattened_verify_signature); tcase_add_test(tc_core, test_rhonabwy_json_flattened_invalid_signature); tcase_add_test(tc_core, test_rhonabwy_parse_json_general_error); tcase_add_test(tc_core, test_rhonabwy_parse_json_general_str); tcase_add_test(tc_core, test_rhonabwy_parse_json_general_t); tcase_add_test(tc_core, test_rhonabwy_json_general_verify_signature_with_all_public_jwks); tcase_add_test(tc_core, test_rhonabwy_json_general_verify_signature_with_one_public_jwks); tcase_add_test(tc_core, test_rhonabwy_json_general_verify_signature_with_jwk); tcase_add_test(tc_core, test_rhonabwy_json_general_invalid_signature); tcase_add_test(tc_core, test_rhonabwy_json_general_verify_signature_with_no_kid); tcase_add_test(tc_core, test_rhonabwy_json_general_invalid_signature_with_no_kid); tcase_add_test(tc_core, test_rhonabwy_json_general_flood); tcase_add_test(tc_core, test_rhonabwy_json_flattened_flood); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS JSON tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_rsa.c000066400000000000000000001004321452472117100162250ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define RS256_TOKEN "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GHUYpRZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_INVALID_HEADER "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GHUYpRZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_INVALID_HEADER_B64 ";error;.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GHUYpRZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_INVALID_PAYLOAD_B64 "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.;error;.GHUYpRZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_INVALID_SIGNATURE "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GHUY6RZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_INVALID_DOTS "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQVGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.GHUYpRZXXKm9rUgJsAgR9-mE-dcqVe802BaVz1jy4Z77QA8jwnPkpjbMAWHQuhmJF7oLsKTlJzn2lI5FM7fDq0V70vC50xvz_eu5KoUveje_Swxo-J2S7Cb64M1qT7X6px8J0sxNnkc07WgKZ8XkSZStbhh_H2z5wRjWC_q0rN8XZE6Bh7K0uW08EVCSNk-fRjD84MVHfDNShOi5iYXbDUnsE_uLxG4uMBu9uUPfq8J3mkqbux26omQqy33fyj-6mCHi50OSV6QoUpJl5apAdSOGd5Tl6lgUKHUBn8ykvJkzIjwJWJWYfiNmGbP7JtCNg4a1f4Jdzn3yIXm824UAiPbRsGmdbTJ7d___eeqXkSOc3rrXBihWByZk0EDt_Zc8enLOC9FhfxQ095n6DUlk1NLb1lq-pwaWUXyqVAp66fMNeltZMFVaTUNaZNCj6woXETJWFwquJLVFFTgQRE-HeUsQ2QGhc3wmqqACghrtKAz1om1Aer1OhZDxhGtfosRIgL2x3JCRkn93SXS3gZTgRL4Uvzc_zqdRqDuHNP1d-j4fg38CBTRFa2mkh1PZX3O7f669c0-ANp0ttqKOoS_6N1Pq8KO-IXfghbXIHLLQyffF78OC_e0QjJODXYPfOBIbh_RsRRMrjTcE_wpeUr_L8KCaKT81a2houfwx_tTYnus" #define RS256_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184YismuCS5PYe0" "Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYvM4Tb5yvvRM7Iz3" "Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKHLFZlL5BTmPWnGIwmmioxI" "RaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_GgWUk17ti2-xAtYG8XEFsv4hzCWip" "x0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4" "d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"kid\":\"1\",\"alg\":\"RS256\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184YismuCS5PYe" "0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYvM4Tb5yvvRM7I" "z3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKHLFZlL5BTmPWnGIwmmi" "oxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_GgWUk17ti2-xAtYG8XEFsv4hz" "CWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bY" "xK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"d\":\"MZrdaw5ETXEnZyXWx5jCW8ZuJUD4MExh8dEwsTGl5d_Nw" "7pW0QqiaK8c4cMdtMnjxSG7gA8_JujcBF8GXraGtlhJnek5JI2AbvbqlXgvu__kI_DiKIyoZLxsFoRV4Nvw7uLj5qlqhIa_x2bRvR5bW15ic738mcQu8eAPSjhKZLEiOpw" "T21IkdI6dmpx2tDGTqJSi9sn5UQL-M8lrnfswdtWsWcjCoo8l3NDYLKpxnUkSxOgjEkpeU6txE5O2540MlzBvIi6Belp2ZxqXxijDIXPS5w7n5A-UvUtR5DZzpa_lz84b5" "9bwtUzfPEPHUSoJjvjRq9BQlw4k2uM7uLzOOmbrIQRbH8byc7Z9DUDK6zRaEW85xVKaXuM7bqcolUuNsHHGGzPGf5pkPYvMV7qACipy9Ksuo8iAGtoZPRan6dO_TfrP0oe" "eowtmg-6S2--lRPjKAHfhPRwqxKp9WKUdEKu1T9TxHOLkWoOJERRBaE7U7RI8kHO3BIaDxPkBzR47llNPr7ufJ0XZQsKx5kSfdNwJfJ_2kNErEe2neKswaIQ9UwTebYYAk" "glvaAs85AdP7-g0VLhF51fipK8Y-9g-hY4VITsEvmxQtS7tRKOgzKOY4PqHRpeB2CTJ4Dvj8JPAfbgWBnXpgh-nrq-37HVr1FLCDkFPqyDIzMur_NxRwSk\",\"p\":\"A" "NXj3t1HDn8OEo_QECNUm1Ie1-xl482FDYvca74igmfVyj017jNwlyl-HlOYYFp9O-hxXF6XLCKtUDk0h_acVOnFeKhYRZCSRlZzGrVjtIX8UtrVkosMxPfqIywl-V5TMLG" "JhdihNhYm02mdXsGk_ksiPXzmjKUxjwPc--kNgZ1rECeFSNCVQDMLHZ0V-W3MVwpxJKU1bc-BpU5hxvANqIfEzgUNpGLet80FAZaHKyWtYzXhRiIggHkJi7K8UjDhraZGH" "wPnfhyAIOAplPfA7zYuB0DIYHshKIQgDWTZ7IVTgzs9B_9OS31FUhXTrcSlNqL-RsE_dxMpPEZLUqOgl08\",\"q\":\"AN-OYtTrB8qNhC80CQV7jJD4pMsFwHmOCihl6" "QBjEj3NfhMP3DtGVhIcX84ZG91QA4NSj9iXswJa9KWpbSNBEzS9bA1AitM0P54_4_jbM9nIX3gXMMwzIbBYrcGuzsvuoz1p4nvWuGHFQhsA9mXiumQ1jj1_7pLopCbl_w9" "eVCafMB2vC55ZloIe5V5L6Ot6I2PenmVEZ4Kgf6DzexHyCXlgYNWP1nKgpE0aRjHAtL3xiBqct-a2HF-kwMH2tbLKmWW3pvNsPWgrsy3h4f2unk5kLCKxn_15gSm8xV4Nr" "54ai-ShQc_QYVr8tXXl_Y2nU9ubUQaA4khhU77G_KOsRj0\",\"qi\":\"ALp3wGNfSv7Ns-S3NlqZB68b4AeykPL59CybNKuaUQkAHkuEfpCaG2lAjeVPrA9UFSio2wKu" "255cwDOTcOkBPhuFeLlegchpWW4tTTyUu1sUYrqUIwhIGxoms4at9sXo3jbtUMe8R4iakfKaGk84ANL_s50uQoCHLevzKalTfItOT5J_7oQYtSZFCxFcZ8w4wDnBLhP4J8" "aFw_wHJZuH9dGGiOeAiJnr4wWWkRuuhHmfsgXxev27NI-dK11-vDaxxgLsCTbltN1_1EuU5bOwO-IUpYOqV3AqfBMfYr8cNgPGAP5dUxWkMV5VCR2efsIBHBmjvVuJv8aZ" "rKsLvqrmRx4\",\"dp\":\"PaCpfzJRD_S7DmrRq4xeMFwotLlq2LWkgI7jEGabElX8LoTSfEnNlCv9ivKVmJ0K3N-E0NBX7CnpuoHTRxAmOzElocPFT3GGCLSjlm4C_rQ" "EH393-M6WFiSFO9w5LJ9loVHRmehhUCKhuYWZXswuZPGZq9o13gcYgPF0N-MnXHcTsX9qyoamd86VGsTRGHzO-3g8KcnqOObO_XWYv2QAEhZ3kecrXT100gLGQVvy56k8s" "7KT5ZNd0QIaGUa_m8v6n7UGjLZvlMCqOExi2rvhcMf0WQsjGXclWGRv14Ye6w9z-WaNXldt0stdamKSZ91-j5oaQuYJZiD0eACN8A1-aw\",\"dq\":\"BKxbUIwhO5C9x" "KbX0W-FvroT59KU9XWMrM-EkWeAyB31lrxsJCkSP4qsTgikVnoHuMUPEL4LFe-E0bm6-FOx7RZQne5NeKDM-6fmQhuC9_iCVmZVtM8U0zTnXPckh4rTisMd4uzYKeMPwLT" "CcdrNfq7H7G0yNYv7cny4Wj_kjnIhdV1lZsgEp2-x58i6c8G336yVrxRA_bAROvIcDoH6xLjJDW3WU8sb5Ci6cuvOW3IjIDtKdN41taIiDWv03GnzzvaJ3OjUV8siEcF5E" "e6GjKj3azo_V_MkShUSIycyFqIDbqIYWBnJDzfdKzvFkyJ-VEbo6LPlBxJRx9ktCtbdGQ\",\"kid\":\"1\",\"alg\":\"RS256\"}"; const char jwk_pubkey_rsa_no_alg_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184Yismu" "CS5PYe0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYv" "M4Tb5yvvRM7Iz3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKH" "LFZlL5BTmPWnGIwmmioxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_G" "gWUk17ti2-xAtYG8XEFsv4hzCWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDyn" "avFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"kid\":\"1\"}"; const char jwk_privkey_rsa_no_alg_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184Yism" "uCS5PYe0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvR" "YvM4Tb5yvvRM7Iz3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2o" "pKHLFZlL5BTmPWnGIwmmioxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpf" "tn_GgWUk17ti2-xAtYG8XEFsv4hzCWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYu" "lkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"d\":\"MZr" "daw5ETXEnZyXWx5jCW8ZuJUD4MExh8dEwsTGl5d_Nw7pW0QqiaK8c4cMdtMnjxSG7gA8_JujcBF8GXraGtlhJnek5JI2AbvbqlXgvu__kI_DiKIyoZLxsFoRV4N" "vw7uLj5qlqhIa_x2bRvR5bW15ic738mcQu8eAPSjhKZLEiOpwT21IkdI6dmpx2tDGTqJSi9sn5UQL-M8lrnfswdtWsWcjCoo8l3NDYLKpxnUkSxOgjEkpeU6txE" "5O2540MlzBvIi6Belp2ZxqXxijDIXPS5w7n5A-UvUtR5DZzpa_lz84b59bwtUzfPEPHUSoJjvjRq9BQlw4k2uM7uLzOOmbrIQRbH8byc7Z9DUDK6zRaEW85xVKa" "XuM7bqcolUuNsHHGGzPGf5pkPYvMV7qACipy9Ksuo8iAGtoZPRan6dO_TfrP0oeeowtmg-6S2--lRPjKAHfhPRwqxKp9WKUdEKu1T9TxHOLkWoOJERRBaE7U7RI" "8kHO3BIaDxPkBzR47llNPr7ufJ0XZQsKx5kSfdNwJfJ_2kNErEe2neKswaIQ9UwTebYYAkglvaAs85AdP7-g0VLhF51fipK8Y-9g-hY4VITsEvmxQtS7tRKOgzK" "OY4PqHRpeB2CTJ4Dvj8JPAfbgWBnXpgh-nrq-37HVr1FLCDkFPqyDIzMur_NxRwSk\",\"p\":\"ANXj3t1HDn8OEo_QECNUm1Ie1-xl482FDYvca74igmfVyj0" "17jNwlyl-HlOYYFp9O-hxXF6XLCKtUDk0h_acVOnFeKhYRZCSRlZzGrVjtIX8UtrVkosMxPfqIywl-V5TMLGJhdihNhYm02mdXsGk_ksiPXzmjKUxjwPc--kNgZ" "1rECeFSNCVQDMLHZ0V-W3MVwpxJKU1bc-BpU5hxvANqIfEzgUNpGLet80FAZaHKyWtYzXhRiIggHkJi7K8UjDhraZGHwPnfhyAIOAplPfA7zYuB0DIYHshKIQgD" "WTZ7IVTgzs9B_9OS31FUhXTrcSlNqL-RsE_dxMpPEZLUqOgl08\",\"q\":\"AN-OYtTrB8qNhC80CQV7jJD4pMsFwHmOCihl6QBjEj3NfhMP3DtGVhIcX84ZG9" "1QA4NSj9iXswJa9KWpbSNBEzS9bA1AitM0P54_4_jbM9nIX3gXMMwzIbBYrcGuzsvuoz1p4nvWuGHFQhsA9mXiumQ1jj1_7pLopCbl_w9eVCafMB2vC55ZloIe5" "V5L6Ot6I2PenmVEZ4Kgf6DzexHyCXlgYNWP1nKgpE0aRjHAtL3xiBqct-a2HF-kwMH2tbLKmWW3pvNsPWgrsy3h4f2unk5kLCKxn_15gSm8xV4Nr54ai-ShQc_Q" "YVr8tXXl_Y2nU9ubUQaA4khhU77G_KOsRj0\",\"qi\":\"ALp3wGNfSv7Ns-S3NlqZB68b4AeykPL59CybNKuaUQkAHkuEfpCaG2lAjeVPrA9UFSio2wKu255c" "wDOTcOkBPhuFeLlegchpWW4tTTyUu1sUYrqUIwhIGxoms4at9sXo3jbtUMe8R4iakfKaGk84ANL_s50uQoCHLevzKalTfItOT5J_7oQYtSZFCxFcZ8w4wDnBLhP" "4J8aFw_wHJZuH9dGGiOeAiJnr4wWWkRuuhHmfsgXxev27NI-dK11-vDaxxgLsCTbltN1_1EuU5bOwO-IUpYOqV3AqfBMfYr8cNgPGAP5dUxWkMV5VCR2efsIBHB" "mjvVuJv8aZrKsLvqrmRx4\",\"dp\":\"PaCpfzJRD_S7DmrRq4xeMFwotLlq2LWkgI7jEGabElX8LoTSfEnNlCv9ivKVmJ0K3N-E0NBX7CnpuoHTRxAmOzEloc" "PFT3GGCLSjlm4C_rQEH393-M6WFiSFO9w5LJ9loVHRmehhUCKhuYWZXswuZPGZq9o13gcYgPF0N-MnXHcTsX9qyoamd86VGsTRGHzO-3g8KcnqOObO_XWYv2QAE" "hZ3kecrXT100gLGQVvy56k8s7KT5ZNd0QIaGUa_m8v6n7UGjLZvlMCqOExi2rvhcMf0WQsjGXclWGRv14Ye6w9z-WaNXldt0stdamKSZ91-j5oaQuYJZiD0eACN" "8A1-aw\",\"dq\":\"BKxbUIwhO5C9xKbX0W-FvroT59KU9XWMrM-EkWeAyB31lrxsJCkSP4qsTgikVnoHuMUPEL4LFe-E0bm6-FOx7RZQne5NeKDM-6fmQhuC9" "_iCVmZVtM8U0zTnXPckh4rTisMd4uzYKeMPwLTCcdrNfq7H7G0yNYv7cny4Wj_kjnIhdV1lZsgEp2-x58i6c8G336yVrxRA_bAROvIcDoH6xLjJDW3WU8sb5Ci6" "cuvOW3IjIDtKdN41taIiDWv03GnzzvaJ3OjUV8siEcF5Ee6GjKj3azo_V_MkShUSIycyFqIDbqIYWBnJDzfdKzvFkyJ-VEbo6LPlBxJRx9ktCtbdGQ\",\"kid\":\"1\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":\"2\"}"; const char jwk_key_symmetric_str[] = "{\"kty\":\"oct\",\"alg\":\"HS256\",\"k\":\"c2VjcmV0Cg\",\"kid\":\"1\"}"; START_TEST(test_rhonabwy_serialize_error_header) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); ck_assert_ptr_eq(r_jws_serialize(NULL, jwk_privkey, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_error_payload) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", "value"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key2", "value2"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_no_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_with_key_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, jwk_privkey, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid_content) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, "error", 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_token) { jws_t * jws; size_t payload_len = 0; const unsigned char * payload = NULL; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_ptr_ne((payload = r_jws_get_payload(jws, &payload_len)), NULL); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_gt(payload_len, 0); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)payload, payload_len)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_key_type) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_key_symmetric_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_kid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); r_jwk_set_property_str(jwk_pubkey, "kid", "42"); r_jws_add_keys(jws, NULL, jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_multiple_keys_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, RS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_RS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str_2), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_RS384), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_RS512), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS RSA function tests"); tc_core = tcase_create("test_rhonabwy_rsa"); tcase_add_test(tc_core, test_rhonabwy_serialize_error_header); tcase_add_test(tc_core, test_rhonabwy_serialize_error_payload); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_no_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_serialize_with_key_ok); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid_content); tcase_add_test(tc_core, test_rhonabwy_parse_token); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_key_type); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_kid); tcase_add_test(tc_core, test_rhonabwy_verify_token_valid); tcase_add_test(tc_core, test_rhonabwy_verify_token_multiple_keys_valid); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_verify_ok); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS RSA tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jws_rsapss.c000066400000000000000000000773701452472117100167710ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define PS256_TOKEN "eyJhbGciOiJQUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.t2G7YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_INVALID_HEADER "eyJhbGciOiJQUzI1NiIsImtpZCI6Ij.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.t2G7YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_INVALID_HEADER_B64 ";error;.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.t2G7YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_INVALID_PAYLOAD_B64 "eyJhbGciOiJQUzI1NiIsImtpZCI6IjEifQ.;error;.t2G7YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_INVALID_SIGNATURE "eyJhbGciOiJQUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.t2G6YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_INVALID_DOTS "eyJhbGciOiJQUzI1NiIsImtpZCI6IjEifQVGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u.t2G7YMKJVZe0U1_ZM7efsGWhSAGia5JN-K4lAk3IX7NsMSrWHwZufBXMYZW6S7t_N8xkWEuAgHOY1etwxXuUdhw8uotA-E66M-fErP8MH-N5yUR2G60g3DkcVD-GwbBCsA-Jzum_psaXMA08-3zBjrvGbldqyM51rcdt2qSDxjZ7yxRVhbFbKD0qPOUH49WZx6Mld9oMMSUoIarJitY9LwIC0cR2lXULIh5E-xia42TsNIw9F7VwPXGdHc7_VBqT7R4soxQjWDmfk5QXSMDw2WTIfEXdI3VJiUQ5qnIAe5WWW-wPsK8ughxHLabKXEQ4j7op8EvhZziLOgntGmqQzDq2vEFqoAWYcChijQvg3Ae-3h3F-oFYo8Wh-lcrNZMxta8Ts7AYrdb7cvE2DAO8Oxl0yWJj7vTBJ1YAlO9Kwlba0EydgGY_Xyrl__amALw8p9hSqdVCrJBjYYza8oq_m6B9P1Q3AuVOSdj15yjURa5Hv_ipM9k76Fi0OobHbzfglXCNmw_qDHGhx7aiud9ZPAM-_9xgiWFuIvorltsFDznSimU3va7qorms4AMJ20moG2nmG6ov79cN5Lebj-vupWkUbZ87nd28jOSAJCtDvR2GN0mwYVdrP5jfaIHDpgOKsNTcvigq_srDUyjU-X79LDPtNKUqAwCV3fS2hiwrwlc" #define PS256_TOKEN_EMPTY_SIGNATURE "eyJhbGciOiJQUzI1NiIsImtpZCI6IjEifQ.VGhlIHRydWUgc2lnbiBvZiBpbnRlbGxpZ2VuY2UgaXMgbm90IGtub3dsZWRnZSBidXQgaW1hZ2luYXRpb24u." const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184YismuCS5PYe0" "Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYvM4Tb5yvvRM7Iz3" "Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKHLFZlL5BTmPWnGIwmmioxI" "RaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_GgWUk17ti2-xAtYG8XEFsv4hzCWip" "x0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4" "d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"kid\":\"1\",\"alg\":\"PS256\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184YismuCS5PYe" "0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYvM4Tb5yvvRM7I" "z3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKHLFZlL5BTmPWnGIwmmi" "oxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_GgWUk17ti2-xAtYG8XEFsv4hz" "CWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bY" "xK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"d\":\"MZrdaw5ETXEnZyXWx5jCW8ZuJUD4MExh8dEwsTGl5d_Nw" "7pW0QqiaK8c4cMdtMnjxSG7gA8_JujcBF8GXraGtlhJnek5JI2AbvbqlXgvu__kI_DiKIyoZLxsFoRV4Nvw7uLj5qlqhIa_x2bRvR5bW15ic738mcQu8eAPSjhKZLEiOpw" "T21IkdI6dmpx2tDGTqJSi9sn5UQL-M8lrnfswdtWsWcjCoo8l3NDYLKpxnUkSxOgjEkpeU6txE5O2540MlzBvIi6Belp2ZxqXxijDIXPS5w7n5A-UvUtR5DZzpa_lz84b5" "9bwtUzfPEPHUSoJjvjRq9BQlw4k2uM7uLzOOmbrIQRbH8byc7Z9DUDK6zRaEW85xVKaXuM7bqcolUuNsHHGGzPGf5pkPYvMV7qACipy9Ksuo8iAGtoZPRan6dO_TfrP0oe" "eowtmg-6S2--lRPjKAHfhPRwqxKp9WKUdEKu1T9TxHOLkWoOJERRBaE7U7RI8kHO3BIaDxPkBzR47llNPr7ufJ0XZQsKx5kSfdNwJfJ_2kNErEe2neKswaIQ9UwTebYYAk" "glvaAs85AdP7-g0VLhF51fipK8Y-9g-hY4VITsEvmxQtS7tRKOgzKOY4PqHRpeB2CTJ4Dvj8JPAfbgWBnXpgh-nrq-37HVr1FLCDkFPqyDIzMur_NxRwSk\",\"p\":\"A" "NXj3t1HDn8OEo_QECNUm1Ie1-xl482FDYvca74igmfVyj017jNwlyl-HlOYYFp9O-hxXF6XLCKtUDk0h_acVOnFeKhYRZCSRlZzGrVjtIX8UtrVkosMxPfqIywl-V5TMLG" "JhdihNhYm02mdXsGk_ksiPXzmjKUxjwPc--kNgZ1rECeFSNCVQDMLHZ0V-W3MVwpxJKU1bc-BpU5hxvANqIfEzgUNpGLet80FAZaHKyWtYzXhRiIggHkJi7K8UjDhraZGH" "wPnfhyAIOAplPfA7zYuB0DIYHshKIQgDWTZ7IVTgzs9B_9OS31FUhXTrcSlNqL-RsE_dxMpPEZLUqOgl08\",\"q\":\"AN-OYtTrB8qNhC80CQV7jJD4pMsFwHmOCihl6" "QBjEj3NfhMP3DtGVhIcX84ZG91QA4NSj9iXswJa9KWpbSNBEzS9bA1AitM0P54_4_jbM9nIX3gXMMwzIbBYrcGuzsvuoz1p4nvWuGHFQhsA9mXiumQ1jj1_7pLopCbl_w9" "eVCafMB2vC55ZloIe5V5L6Ot6I2PenmVEZ4Kgf6DzexHyCXlgYNWP1nKgpE0aRjHAtL3xiBqct-a2HF-kwMH2tbLKmWW3pvNsPWgrsy3h4f2unk5kLCKxn_15gSm8xV4Nr" "54ai-ShQc_QYVr8tXXl_Y2nU9ubUQaA4khhU77G_KOsRj0\",\"qi\":\"ALp3wGNfSv7Ns-S3NlqZB68b4AeykPL59CybNKuaUQkAHkuEfpCaG2lAjeVPrA9UFSio2wKu" "255cwDOTcOkBPhuFeLlegchpWW4tTTyUu1sUYrqUIwhIGxoms4at9sXo3jbtUMe8R4iakfKaGk84ANL_s50uQoCHLevzKalTfItOT5J_7oQYtSZFCxFcZ8w4wDnBLhP4J8" "aFw_wHJZuH9dGGiOeAiJnr4wWWkRuuhHmfsgXxev27NI-dK11-vDaxxgLsCTbltN1_1EuU5bOwO-IUpYOqV3AqfBMfYr8cNgPGAP5dUxWkMV5VCR2efsIBHBmjvVuJv8aZ" "rKsLvqrmRx4\",\"dp\":\"PaCpfzJRD_S7DmrRq4xeMFwotLlq2LWkgI7jEGabElX8LoTSfEnNlCv9ivKVmJ0K3N-E0NBX7CnpuoHTRxAmOzElocPFT3GGCLSjlm4C_rQ" "EH393-M6WFiSFO9w5LJ9loVHRmehhUCKhuYWZXswuZPGZq9o13gcYgPF0N-MnXHcTsX9qyoamd86VGsTRGHzO-3g8KcnqOObO_XWYv2QAEhZ3kecrXT100gLGQVvy56k8s" "7KT5ZNd0QIaGUa_m8v6n7UGjLZvlMCqOExi2rvhcMf0WQsjGXclWGRv14Ye6w9z-WaNXldt0stdamKSZ91-j5oaQuYJZiD0eACN8A1-aw\",\"dq\":\"BKxbUIwhO5C9x" "KbX0W-FvroT59KU9XWMrM-EkWeAyB31lrxsJCkSP4qsTgikVnoHuMUPEL4LFe-E0bm6-FOx7RZQne5NeKDM-6fmQhuC9_iCVmZVtM8U0zTnXPckh4rTisMd4uzYKeMPwLT" "CcdrNfq7H7G0yNYv7cny4Wj_kjnIhdV1lZsgEp2-x58i6c8G336yVrxRA_bAROvIcDoH6xLjJDW3WU8sb5Ci6cuvOW3IjIDtKdN41taIiDWv03GnzzvaJ3OjUV8siEcF5E" "e6GjKj3azo_V_MkShUSIycyFqIDbqIYWBnJDzfdKzvFkyJ-VEbo6LPlBxJRx9ktCtbdGQ\",\"kid\":\"1\",\"alg\":\"PS256\"}"; const char jwk_pubkey_rsa_no_alg_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184Yismu" "CS5PYe0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvRYv" "M4Tb5yvvRM7Iz3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2opKH" "LFZlL5BTmPWnGIwmmioxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpftn_G" "gWUk17ti2-xAtYG8XEFsv4hzCWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYulkDyn" "avFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"kid\":\"1\"}"; const char jwk_privkey_rsa_no_alg_str[] = "{\"kty\":\"RSA\",\"n\":\"ALrIdhuABv82Y7K1-LJCXRy1LVdmK9IAHwmmlI-HnOrFeEsSwuCeblUgEpqz_mj7lLtZN0Gnlz-7U0hOpGCeOYXRMn8184Yism" "uCS5PYe0Jfot0kMumF2IOBV94AGBSeWQcK8J-Ed3X-rkR9vovv8gXhKyRDQH4mon_cPwtdCi2PScnRlkvlOjYkib9m0QQqpvjmcd02s8BYtakRVRva2mQT_dCvR" "YvM4Tb5yvvRM7Iz3Ni6Jj-IOUZvaZtRW_2HPvhho6Pj_XuYDVHHWyi8SWXtvMQehOtiv9cNecOcvtvEN7YLf2sTM9nIBxOmkRF6k2wvmxwMeoqQZ-pZuvVQkn2o" "pKHLFZlL5BTmPWnGIwmmioxIRaDmc1KApufOw2voHqCSJR99UMwIyJpIulFqBw_F2y2vS-uXDODA3PmG1u1qpN2mqjvbHz1PwKYucPQH1GoMMRKeEPsjKamLLpf" "tn_GgWUk17ti2-xAtYG8XEFsv4hzCWipx0zh4S0aVRLoomN9AisHTCWpOgdg1kFj3ECrKxhYMETWGUTKrItAOhE1VuyOenIPMN8ZEeWfqPdUnrRYtRN0ce7WCYu" "lkDynavFJK_13NpJ7d-44ns_F2r2Bl9K6bYxK8W4d2Q9soCtfsb6eOabtuP-5yWuvPxn9gt6xgbIMEc643k__Lx2_ct6fT\",\"e\":\"AQAB\",\"d\":\"MZr" "daw5ETXEnZyXWx5jCW8ZuJUD4MExh8dEwsTGl5d_Nw7pW0QqiaK8c4cMdtMnjxSG7gA8_JujcBF8GXraGtlhJnek5JI2AbvbqlXgvu__kI_DiKIyoZLxsFoRV4N" "vw7uLj5qlqhIa_x2bRvR5bW15ic738mcQu8eAPSjhKZLEiOpwT21IkdI6dmpx2tDGTqJSi9sn5UQL-M8lrnfswdtWsWcjCoo8l3NDYLKpxnUkSxOgjEkpeU6txE" "5O2540MlzBvIi6Belp2ZxqXxijDIXPS5w7n5A-UvUtR5DZzpa_lz84b59bwtUzfPEPHUSoJjvjRq9BQlw4k2uM7uLzOOmbrIQRbH8byc7Z9DUDK6zRaEW85xVKa" "XuM7bqcolUuNsHHGGzPGf5pkPYvMV7qACipy9Ksuo8iAGtoZPRan6dO_TfrP0oeeowtmg-6S2--lRPjKAHfhPRwqxKp9WKUdEKu1T9TxHOLkWoOJERRBaE7U7RI" "8kHO3BIaDxPkBzR47llNPr7ufJ0XZQsKx5kSfdNwJfJ_2kNErEe2neKswaIQ9UwTebYYAkglvaAs85AdP7-g0VLhF51fipK8Y-9g-hY4VITsEvmxQtS7tRKOgzK" "OY4PqHRpeB2CTJ4Dvj8JPAfbgWBnXpgh-nrq-37HVr1FLCDkFPqyDIzMur_NxRwSk\",\"p\":\"ANXj3t1HDn8OEo_QECNUm1Ie1-xl482FDYvca74igmfVyj0" "17jNwlyl-HlOYYFp9O-hxXF6XLCKtUDk0h_acVOnFeKhYRZCSRlZzGrVjtIX8UtrVkosMxPfqIywl-V5TMLGJhdihNhYm02mdXsGk_ksiPXzmjKUxjwPc--kNgZ" "1rECeFSNCVQDMLHZ0V-W3MVwpxJKU1bc-BpU5hxvANqIfEzgUNpGLet80FAZaHKyWtYzXhRiIggHkJi7K8UjDhraZGHwPnfhyAIOAplPfA7zYuB0DIYHshKIQgD" "WTZ7IVTgzs9B_9OS31FUhXTrcSlNqL-RsE_dxMpPEZLUqOgl08\",\"q\":\"AN-OYtTrB8qNhC80CQV7jJD4pMsFwHmOCihl6QBjEj3NfhMP3DtGVhIcX84ZG9" "1QA4NSj9iXswJa9KWpbSNBEzS9bA1AitM0P54_4_jbM9nIX3gXMMwzIbBYrcGuzsvuoz1p4nvWuGHFQhsA9mXiumQ1jj1_7pLopCbl_w9eVCafMB2vC55ZloIe5" "V5L6Ot6I2PenmVEZ4Kgf6DzexHyCXlgYNWP1nKgpE0aRjHAtL3xiBqct-a2HF-kwMH2tbLKmWW3pvNsPWgrsy3h4f2unk5kLCKxn_15gSm8xV4Nr54ai-ShQc_Q" "YVr8tXXl_Y2nU9ubUQaA4khhU77G_KOsRj0\",\"qi\":\"ALp3wGNfSv7Ns-S3NlqZB68b4AeykPL59CybNKuaUQkAHkuEfpCaG2lAjeVPrA9UFSio2wKu255c" "wDOTcOkBPhuFeLlegchpWW4tTTyUu1sUYrqUIwhIGxoms4at9sXo3jbtUMe8R4iakfKaGk84ANL_s50uQoCHLevzKalTfItOT5J_7oQYtSZFCxFcZ8w4wDnBLhP" "4J8aFw_wHJZuH9dGGiOeAiJnr4wWWkRuuhHmfsgXxev27NI-dK11-vDaxxgLsCTbltN1_1EuU5bOwO-IUpYOqV3AqfBMfYr8cNgPGAP5dUxWkMV5VCR2efsIBHB" "mjvVuJv8aZrKsLvqrmRx4\",\"dp\":\"PaCpfzJRD_S7DmrRq4xeMFwotLlq2LWkgI7jEGabElX8LoTSfEnNlCv9ivKVmJ0K3N-E0NBX7CnpuoHTRxAmOzEloc" "PFT3GGCLSjlm4C_rQEH393-M6WFiSFO9w5LJ9loVHRmehhUCKhuYWZXswuZPGZq9o13gcYgPF0N-MnXHcTsX9qyoamd86VGsTRGHzO-3g8KcnqOObO_XWYv2QAE" "hZ3kecrXT100gLGQVvy56k8s7KT5ZNd0QIaGUa_m8v6n7UGjLZvlMCqOExi2rvhcMf0WQsjGXclWGRv14Ye6w9z-WaNXldt0stdamKSZ91-j5oaQuYJZiD0eACN" "8A1-aw\",\"dq\":\"BKxbUIwhO5C9xKbX0W-FvroT59KU9XWMrM-EkWeAyB31lrxsJCkSP4qsTgikVnoHuMUPEL4LFe-E0bm6-FOx7RZQne5NeKDM-6fmQhuC9" "_iCVmZVtM8U0zTnXPckh4rTisMd4uzYKeMPwLTCcdrNfq7H7G0yNYv7cny4Wj_kjnIhdV1lZsgEp2-x58i6c8G336yVrxRA_bAROvIcDoH6xLjJDW3WU8sb5Ci6" "cuvOW3IjIDtKdN41taIiDWv03GnzzvaJ3OjUV8siEcF5Ee6GjKj3azo_V_MkShUSIycyFqIDbqIYWBnJDzfdKzvFkyJ-VEbo6LPlBxJRx9ktCtbdGQ\",\"kid\":\"1\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":\"2\"}"; #if GNUTLS_VERSION_NUMBER >= 0x030600 START_TEST(test_rhonabwy_serialize_error_header) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); ck_assert_ptr_eq(r_jws_serialize(NULL, jwk_privkey, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_error_payload) { jws_t * jws; jwk_t * jwk_privkey; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_PS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_eq(r_jws_serialize(jws, NULL, 0), NULL); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_PS256), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key", "value"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); ck_assert_int_eq(r_jws_set_header_str_value(jws, "key2", "value2"), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_no_set_alg_serialize_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws, jwk_privkey, NULL), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, NULL, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_serialize_with_key_ok) { jws_t * jws; jwk_t * jwk_privkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws, R_JWA_ALG_PS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws, jwk_privkey, 0)), NULL); o_free(token); r_jws_free(jws); r_jwk_free(jwk_privkey); } END_TEST START_TEST(test_rhonabwy_parse_token_invalid_content) { jws_t * jws; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_INVALID_HEADER, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_INVALID_PAYLOAD_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jws_parse(jws, "error", 0), RHN_ERROR_PARAM); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_parse_token) { jws_t * jws; size_t payload_len = 0; const unsigned char * payload = NULL; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN, 0), RHN_OK); ck_assert_ptr_ne((payload = r_jws_get_payload(jws, &payload_len)), NULL); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_gt(payload_len, 0); ck_assert_int_eq(0, o_strncmp(PAYLOAD, (const char *)payload, payload_len)); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN_EMPTY_SIGNATURE, 0), RHN_ERROR_PARAM); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_invalid_kid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); r_jwk_set_property_str(jwk_pubkey, "kid", "42"); r_jws_add_keys(jws, NULL, jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_ERROR_INVALID); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws, jwk_pubkey, 0), RHN_OK); r_jws_free(jws); r_jwk_free(jwk_pubkey); } END_TEST START_TEST(test_rhonabwy_verify_token_multiple_keys_valid) { jws_t * jws; jwk_t * jwk_pubkey; ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_eq(r_jws_parse(jws, PS256_TOKEN, 0), RHN_OK); ck_assert_int_eq(R_JWA_ALG_PS256, r_jws_get_alg(jws)); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str_2), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_str), RHN_OK); r_jws_add_keys(jws, NULL, jwk_pubkey); r_jwk_free(jwk_pubkey); ck_assert_int_eq(r_jws_verify_signature(jws, NULL, 0), RHN_OK); r_jws_free(jws); } END_TEST START_TEST(test_rhonabwy_set_alg_serialize_verify_ok) { jws_t * jws_sign, * jws_verify; jwk_t * jwk_privkey, * jwk_pubkey; char * token = NULL; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_sign), RHN_OK); ck_assert_int_eq(r_jws_init(&jws_verify), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, jwk_privkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey, jwk_pubkey_rsa_no_alg_str), RHN_OK); ck_assert_int_eq(r_jws_set_payload(jws_sign, (const unsigned char *)PAYLOAD, o_strlen(PAYLOAD)), RHN_OK); ck_assert_int_eq(r_jws_add_keys(jws_sign, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_PS256), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_PS384), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); ck_assert_int_eq(r_jws_set_alg(jws_sign, R_JWA_ALG_PS512), RHN_OK); ck_assert_ptr_ne((token = r_jws_serialize(jws_sign, NULL, 0)), NULL); ck_assert_int_eq(r_jws_parse(jws_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jws_verify_signature(jws_verify, jwk_pubkey, 0), RHN_OK); o_free(token); r_jws_free(jws_sign); r_jws_free(jws_verify); r_jwk_free(jwk_privkey); r_jwk_free(jwk_pubkey); } END_TEST #endif static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWS RSA PSS function tests"); tc_core = tcase_create("test_rhonabwy_rsapss"); #if GNUTLS_VERSION_NUMBER >= 0x030600 tcase_add_test(tc_core, test_rhonabwy_serialize_error_header); tcase_add_test(tc_core, test_rhonabwy_serialize_error_payload); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_no_set_alg_serialize_ok); tcase_add_test(tc_core, test_rhonabwy_serialize_with_key_ok); tcase_add_test(tc_core, test_rhonabwy_parse_token_invalid_content); tcase_add_test(tc_core, test_rhonabwy_parse_token); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_token_invalid_kid); tcase_add_test(tc_core, test_rhonabwy_verify_token_valid); tcase_add_test(tc_core, test_rhonabwy_verify_token_multiple_keys_valid); tcase_add_test(tc_core, test_rhonabwy_set_alg_serialize_verify_ok); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWS RSA PSS tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwt_core.c000066400000000000000000003665441452472117100164130ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #include #include #include const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"use\":\"enc\",\"kid\":\"1\"}"; const char jwk_privkey_ecdsa_str[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x\":\"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4\","\ "\"y\":\"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM\",\"d\":\"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE\","\ "\"use\":\"enc\",\"kid\":\"1\"}"; const unsigned char symmetric_key[] = "my-very-secret"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; const unsigned char rsa_2048_priv[] = "-----BEGIN PRIVATE KEY-----\n" "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDC2kwAziXUf33m\n" "iqWp0yG6o259+nj7hpQLC4UT0Hmz0wmvreDJ/yNbSgOvsxvVdvzL2IaRZ+Gi5mo0\n" "lswWvL6IGz7PZO0kXTq9sdBnNqMOx27HddV9e/2/p0MgibJTbgywY2Sk23QYhJpq\n" "Kq/nU0xlBfSaI5ddZ2RC9ZNkVeGawUKYksTruhAVJqviHN8BoK6VowP5vcxyyOWH\n" "TK9KruDqzCIhqwRTeo0spokBkTN/LCuhVivcHAzUiJVtB4qAiTI9L/zkzhjpKz9P\n" "45aLU54rj011gG8U/6E1USh5nMnPkr+d3oLfkhfS3Zs3kJVdyFQWZpQxiTaI92Fd\n" "2wLvbS0HAgMBAAECggEAD8dTnkETSSjlzhRuI9loAtAXM3Zj86JLPLW7GgaoxEoT\n" "n7lJ2bGicFMHB2ROnbOb9vnas82gtOtJsGaBslmoaCckp/C5T1eJWTEb+i+vdpPp\n" "wZcmKZovyyRFSE4+NYlU17fEv6DRvuaGBpDcW7QgHJIl45F8QWEM+msee2KE+V4G\n" "z/9vAQ+sOlvsb4mJP1tJIBx9Lb5loVREwCRy2Ha9tnWdDNar8EYkOn8si4snPT+E\n" "3ZCy8mlcZyUkZeiS/HdtydxZfoiwrSRYamd1diQpPhWCeRteQ802a7ds0Y2YzgfF\n" "UaYjNuRQm7zA//hwbXS7ELPyNMU15N00bajlG0tUOQKBgQDnLy01l20OneW6A2cI\n" "DIDyYhy5O7uulsaEtJReUlcjEDMkin8b767q2VZHb//3ZH+ipnRYByUUyYUhdOs2\n" "DYRGGeAebnH8wpTT4FCYxUsIUpDfB7RwfdBONgaKewTJz/FPswy1Ye0b5H2c6vVi\n" "m2FZ33HQcoZ3wvFFqyGVnMzpOwKBgQDXxL95yoxUGKa8vMzcE3Cn01szh0dFq0sq\n" "cFpM+HWLVr84CItuG9H6L0KaStEEIOiJsxOVpcXfFFhsJvOGhMA4DQTwH4WuXmXp\n" "1PoVMDlV65PYqvhzwL4+QhvZO2bsrEunITXOmU7CI6kilnAN3LuP4HbqZgoX9lqP\n" "I31VYzLupQKBgGEYck9w0s/xxxtR9ILv5XRnepLdoJzaHHR991aKFKjYU/KD7JDK\n" "INfoAhGs23+HCQhCCtkx3wQVA0Ii/erM0II0ueluD5fODX3TV2ZibnoHW2sgrEsW\n" "vFcs36BnvIIaQMptc+f2QgSV+Z/fGsKYadG6Q+39O7au/HB7SHayzWkjAoGBAMgt\n" "Fzslp9TpXd9iBWjzfCOnGUiP65Z+GWkQ/SXFqD+SRir0+m43zzGdoNvGJ23+Hd6K\n" "TdQbDJ0uoe4MoQeepzoZEgi4JeykVUZ/uVfo+nh06yArVf8FxTm7WVzLGGzgV/uA\n" "+wtl/cRtEyAsk1649yW/KHPEIP8kJdYAJeoO8xSlAoGAERMrkFR7KGYZG1eFNRdV\n" "mJMq+Ibxyw8ks/CbiI+n3yUyk1U8962ol2Q0T4qjBmb26L5rrhNQhneM4e8mo9FX\n" "LlQapYkPvkdrqW0Bp72A/UNAvcGTmN7z5OCJGMUutx2hmEAlrYmpLKS8pM/p9zpK\n" "tEOtzsP5GMDYVlEp1jYSjzQ=\n" "-----END PRIVATE KEY-----\n"; #define JWT_CLAIM_ISS "https://rhonabwy.tld" #define JWT_CLAIM_SUB "rhon_sub" #define JWT_CLAIM_AUD1 "dave_lopper" #define JWT_CLAIM_AUD2 "sam_gamegie" #define JWT_CLAIM_AUD3 "monica_rambeau" #define JWT_CLAIM_EXP 30 #define JWT_CLAIM_NBF 30 #define JWT_CLAIM_IAT 30 #define JWT_CLAIM_JTI "jit1234Xyz" #define JWT_CLAIM_SCOPE "scope1" #define JWT_CLAIM_AGE 42 #define JWT_CLAIM_VERIFIED json_true() #define JWT_CLAIM_TYP "jwt+rhnabwy" #define JWT_CLAIM_CTY "application/mater" #define JWT_CLAIM_AMR_1 "password" #define JWT_CLAIM_AMR_2 "otp" #define JWT_CLAIM_AMR_3 "webauthn" #define CLAIM_STR "grut" #define CLAIM_INT 42 unsigned char cypher_key[] = {4, 211, 31, 197, 84, 157, 252, 254, 11, 100, 157, 250, 63, 170, 106, 206, 107, 124, 212, 45, 111, 107, 9, 219, 200, 177, 0, 240, 143, 156, 44, 207}; unsigned char iv[] = {3, 22, 60, 12, 43, 67, 104, 105, 108, 108, 105, 99, 111, 116, 104, 101}; const char pubkey[] = "{\"kty\":\"RSA\","\ "\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl"\ "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre"\ "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_"\ "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI"\ "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU"\ "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\","\ "\"e\":\"AQAB\"}"; #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define HTTPS_CERT_KEY "cert/server.key" #define HTTPS_CERT_PEM "cert/server.crt" const unsigned char advanced_key_1[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIAYMcQvkJcMXw5WYHEL05zOvksZ3JG6WAVc4PqupNxncoAoGCCqGSM49\n" "AwEHoUQDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5\n" "plYuZz2/TzJbrwPDUYCB/rV8/hHku0tXnA==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_1[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu\n" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg\n" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG\n" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1\n" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF\n" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1\n" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd\n" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2\n" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU\n" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv\n" "s3yOHp3+WqTOfToYSrrNz2rP\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_1[] = "MIIDDjCCAXagAwIBAgIUNdBXsS0f7w7zoqBV005eOeD2DMgwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzhaFw0yMjA4MjkyMTQ5MzhaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEKOIR+UzdL4i9/nP35uX5RIafqwsADRFiN74McMa3LVL/TDfougV5plYu" "Zz2/TzJbrwPDUYCB/rV8/hHku0tXnKN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBR/xAPVMRUg" "SF2INrNsGrX9ZikSYDAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAHH8FtJ4CVfrSvlGxRkZH91XFK6ib110b/Nu9zIPG" "2t+GaFhvCBtRfHhbzF7FG/o+NNhbUfWLnbPReNQy45QasqlrQMDkgeCAZskeadx1" "MjrAN8EbFSmQxQ9dKJwZrXYxiT3IW1LFWyuHHA+avDyWyDQSoABZkVWzV3UHj6PF" "GjNUhdWbU7WLF9zYX07K7u2FyV67/fJCPX9R1+cvVFpYtPQsOo5NFnELrlbRs8d1" "g7JpfZX/juXBtYsiA71iOP9sVqWHM5UkWgd6xadOGFqiiSpJMn+k5LL9PVLZ6Bqd" "qLOEFELIULM/mVvIvd3kbwiTiUkZTb6wtI/Z8bAPlKSQB/xHuxy8/H3cOc8COoq2" "fnTtLBaQj4c4VEk+MPuLsK7smFWsQnQNRS+uHPIPW4Nv6nyUj54tqe8FaIzEioBU" "D779sJ9gxiz68UPDo5ArHx3i2iS2ROkEGEUm93fYGi8y8yZtWb8MsPvqJi2Ar0tv" "s3yOHp3+WqTOfToYSrrNz2rP"; const unsigned char advanced_key_2[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEICXdcvJ68jTD5qOxv5a1QQLE7K6OcqSOjgNLd3pPE1z1oAoGCCqGSM49\n" "AwEHoUQDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3\n" "n5/ijLyQ54f6bWnLkxeuZxRfTdrDHNodOg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_2[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i\n" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE\n" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y\n" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A\n" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A\n" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP\n" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J\n" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy\n" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV\n" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE\n" "TrY5XLCqtITFRVTMubJPyDnc\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_2[] = "MIIDDjCCAXagAwIBAgIUd1sYeALcC3nDDzlovmUm9S+IAaEwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDZaFw0yMjA4MzAxNTI0NDZaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAEO/I3Q8FsEFii5oHZB5HtZe46awSYxkmTtmVpWKab5T9SIfznVwL3n5/i" "jLyQ54f6bWnLkxeuZxRfTdrDHNodOqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdjs0rqLgE" "HvJoen2T0XIRRirS5TAfBgNVHSMEGDAWgBSTmEmG+THW/zrJM5ZfCPi259RA8zAN" "BgkqhkiG9w0BAQsFAAOCAYEAECdRtFVERpkkAfj7mwC7Qu2nopMYcKCDagDKi16Y" "JELQWDEx1djR9GFu19QERN0RGSOEgzPunifaUOGfkYsFaF9NA27KVGgpK3TgTl5A" "JBIGIiKP8vSiqF6KOosbTU3WeKwT4mE3t1yWcG/ExCqXUcOUmH2BFMh74aO2yp8A" "FiRAK51AlU7L3WRvdtaVL1rriiYnOh5SrSevVvebMdZxOzsl7wGhpW6gVfm0xmMP" "KdCNhyjTlX6UzRDGpNxT5TNb3kYRGviZ/BsMpT1MrnIQRUUhLEz7dd4362XgRX1J" "i6RvDKcQVxQNdIOTWyJIDenrbqmuA4ZeV/OI86Uf9iPkjKUGJiVhaYMWwgXSkfRy" "U3uAVpelLX7/mzm3PuJV5RyBsJqNsumsdDSkA++5VhdOqi8Yr5gI0gF3ep5tggvV" "BKgGmpZ2fEF6BKMTC4HyiCc9e2qeqLTIOZPiMpJm8N6fpEY37JEqqPHeY19WYxdE" "TrY5XLCqtITFRVTMubJPyDnc"; const unsigned char advanced_key_3[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIEslWGWIe3xz8KResadYE+JZEfrPNp4wV7b19He998GLoAoGCCqGSM49\n" "AwEHoUQDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABU\n" "Xm1qDJIFMq/Ct9//ZMw3cHcvzJSDsqOuLQ==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_3[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUF6BNJxZDAJ79e+0I4OStbeBHNB4wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTMyMTQ5NDBaFw0yMjA4MjkyMTQ5NDBaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAEB8zD2LcZJt8GFMS07Z9k0aWm4r4VFOAm7BQOJzgsIUkFbVxKfABUXm1q\n" "DJIFMq/Ct9//ZMw3cHcvzJSDsqOuLaN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBSdgOkpqrAK\n" "R71zgTVIPfKcF40SAzAfBgNVHSMEGDAWgBREM51ULZjY5niamwAnB62dRTAjZDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAHe+d5uxOBNW+6o9gyn+g2Q1x0YFJhaCvvgoVVC71\n" "E1WkdBMO0nRYJZNxmNgd13DNvrD+Y31IFmTgGidg9urDq6HLo9Q9UkpAYdOKTsXk\n" "NDo1QL5Kjqspuf2Aco3cDcvR2a5OUAJigftpdjOSTvG3geltDsYcd/khY0dMOl3h\n" "25OZm6KyZAORWw3LhXxtmDfPxe31cd/lEp19Gp8aokLorHc7/yYS5h4OhL146vm/\n" "CHYSt8pAIP65IyKoHJpHdSc4uOz0HJ92lpR10Qa9wqrFzDVcHGDX/JBvS0/H5Uyd\n" "OY4jO7FEImq434YOtSy0yGJh/soK8RNe0frGzoQsQ/WxMBeHnprp/eBVZ8jqvYJ4\n" "GW8kTtl8SGitehjoFdby46nAzdt3dBUcmZhm9Yka4jRVN5mwd+s13Pu2zRSvEwvq\n" "IiKlSjZYotFffUsrfHVYqlk58PX5j7P/fohvLnHkucbu9FVrvVLlqZHK3vzafdw6\n" "SlefNWD4/90X/5VFOpePkjZY\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_3[] = "MIIDDjCCAXagAwIBAgIUcqJBzjg4lb0vBeFBGZ2uuY9ZoLkwDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMTETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTMyMTQ5MzlaFw0yMjA4MjkyMTQ5MzlaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAE/TPAuX0MdUL6H1xse1VwixvR6wxmy6+GS5XS4P8H6lcczryuu+8Oqz2h" "6sw1ChDIRt00l25j92h1SjFknnbE2qN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBScRf4VnU2d" "71JxFeUmXa5uqaMclTAfBgNVHSMEGDAWgBRZm42kTC+aL+0DVOySIDIN9SvUEjAN" "BgkqhkiG9w0BAQsFAAOCAYEAmhXg8uHQcAttx1gOKrLi77q1RpeGIu4dYy0UtOW1" "ucNJuOGs8prcPROPElZEkZmfcgwDd2wwjNfs8tqPrcgSDyipLG7yMEj3uxxSZW7S" "DN72f3qL2QavZ4joVZI5v2VplBFbCqC3Fr06Pg8xRcihfb+SnsrhQ4hVuG6GxIF+" "n/khTXsEW6kEi6V0s79AIFBzYa/nH3sfK4gWQvcmUoBJ3Hzz2EIroB9v+P8OdJcR" "37pfw+IDZx2Ri/W18nLwDTF0NVydT2ZGxHRFjankV2uM5q79nW1fsRCTrfoKxWGN" "pKG9IxeXORwv87pETRxQA8W08AGqBsk62f5/lEuxfJqIw6wZKLtb2nqN912QDXLc" "q0F6StYQHYB7WMZM2FA3AzaYeCjfI5a1/LirKm8okt96HXVo2rpqaDB3sJq5C5u+" "yUZ3i+PlDEkUv3CTYSVYaBjKBDTgj6Z4kxKTdBE/A5rXRwIi14LyddTcPRKDrHlh" "MQJL7ADzfeTbVYOHJx8XEE0F"; const unsigned char advanced_key_4[] = "-----BEGIN EC PRIVATE KEY-----\n" "MHcCAQEEIF+8UMnI9we1opth9BXqoNmsyj7bpeyMl6gnj8y4jejaoAoGCCqGSM49\n" "AwEHoUQDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6\n" "KeiN/+ym/O780uZLwqCaFR9ix5I3/Jxpdg==\n" "-----END EC PRIVATE KEY-----"; const unsigned char advanced_cert_pem_4[] = "-----BEGIN CERTIFICATE-----\n" "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL\n" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe\n" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg\n" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN\n" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE\n" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho\n" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN\n" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA\n" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw\n" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw\n" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a\n" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8\n" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ\n" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N\n" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa\n" "Cggnp64OVIyU5OqLa4BVmWQl\n" "-----END CERTIFICATE-----"; const unsigned char advanced_cert_der_4[] = "MIIDDjCCAXagAwIBAgIUVWRCzRVkKkvSV8p5hX2em+k5NH0wDQYJKoZIhvcNAQEL" "BQAwKjETMBEGA1UEAwwKZ2xld2x3eWRfMjETMBEGA1UEChMKYmFiZWxvdWVzdDAe" "Fw0yMTA5MTQxNTI0NDdaFw0yMjA4MzAxNTI0NDdaMCsxFDASBgNVBAMTC0RhdmUg" "TG9wcGVyMRMwEQYDVQQKEwpiYWJlbG91ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D" "AQcDQgAErXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLdF/27T27R6KeiN" "/+ym/O780uZLwqCaFR9ix5I3/JxpdqN2MHQwDAYDVR0TAQH/BAIwADATBgNVHSUE" "DDAKBggrBgEFBQcDAjAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBTLd4oWdCho" "wKLuBKrx0Gq1C8W4mDAfBgNVHSMEGDAWgBRK5ldhst/tVyTQRn8g0Sc3gWnqkDAN" "BgkqhkiG9w0BAQsFAAOCAYEAjq6QQM2ghdIvYkPwVV1r3oovuX9jTflslmzcZhuA" "Mf41hKXjx/Y56n5YgWm6IeDWNfD7Q0u+ewe9k8sOA/6SROlrhW/1mFSVUDACd0uw" "NubxeQQBLuYC+aoXOVacWX3zPXti7AcmYCHXtHnIp9ug3mYPyXg5idKRAqaaujZw" "lN9DXB8L40PcujjzG/2rYhUx0xasyZZsbUotwn8YxvqPtEFls/3KWNTguu64VE3a" "ha+NYJHcyyK8anNSTGV2snHNyCQagvb/lu+hsLYx3QkfknqWnbLHaA5Be86jZNQ8" "EfAKsVN2N1NsIZfeRJ7jkeoFztI+sEuJjXEKJfQ69KoDAiIVfNuooMlYH9r2ldCJ" "WZp5QzZ+cMXLrf3quKudH6QvdD0uKkHX9vQ9pfMDhMNgAbrUyI4dMgWJcW788N1N" "Yj7MxshEtderX2xwlf0atGNyj/MQjhiuBzYCuvbzLxD8CkZMMjPwEHbwGkVaSdTa" "Cggnp64OVIyU5OqLa4BVmWQl"; const char advanced_jku_4[] = "{\"keys\":[{\"kty\":\"EC\",\"x\":\"rXNalVG5Ylar4cutzXQVVA02QJLCo7b21E3C2nHhBLc\",\"y\":\"Rf9u09u0einojf_spvzu_NLmS8KgmhUfYseSN_ycaXY\",\"crv\":\"P-256\",\"kid\":\"OsipzlLJ1CAOU_WnT2zuB4u31IlgFPsZfT4j4r5qZUA\"}]}"; #define ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY "eyJqd2siOnsia3R5IjoiRUMiLCJ4IjoiS09JUi1VemRMNGk5X25QMzV1WDVSSWFmcXdzQURSRmlONzRNY01hM0xWSSIsInkiOiJfMHczNkxvRmVhWldMbWM5djA4eVc2OER3MUdBZ2Y2MWZQNFI1THRMVjV3IiwiY3J2IjoiUC0yNTYiLCJraWQiOiIxIiwieDVjIjpbIk1JSUREakNDQVhhZ0F3SUJBZ0lVTmRCWHNTMGY3dzd6b3FCVjAwNWVPZUQyRE1nd0RRWUpLb1pJaHZjTkFRRUxCUUF3S2pFVE1CRUdBMVVFQXd3S1oyeGxkMngzZVdSZk1URVRNQkVHQTFVRUNoTUtZbUZpWld4dmRXVnpkREFlRncweU1UQTVNVE15TVRRNU16aGFGdzB5TWpBNE1qa3lNVFE1TXpoYU1Dc3hGREFTQmdOVkJBTVRDMFJoZG1VZ1RHOXdjR1Z5TVJNd0VRWURWUVFLRXdwaVlXSmxiRzkxWlhOME1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUtPSVIrVXpkTDRpOS9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkwvVERmb3VnVjVwbFl1WnoyL1R6SmJyd1BEVVlDQi9yVjgvaEhrdTB0WG5LTjJNSFF3REFZRFZSMFRBUUgvQkFJd0FEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFQQmdOVkhROEJBZjhFQlFNREI0QUFNQjBHQTFVZERnUVdCQlIveEFQVk1SVWdTRjJJTnJOc0dyWDlaaWtTWURBZkJnTlZIU01FR0RBV2dCUlptNDJrVEMrYUwrMERWT3lTSURJTjlTdlVFakFOQmdrcWhraUc5dzBCQVFzRkFBT0NBWUVBSEg4RnRKNENWZnJTdmxHeFJrWkg5MVhGSzZpYjExMGIvTnU5eklQRzJ0K0dhRmh2Q0J0UmZIaGJ6RjdGRy9vK05OaGJVZldMbmJQUmVOUXk0NVFhc3FsclFNRGtnZUNBWnNrZWFkeDFNanJBTjhFYkZTbVF4UTlkS0p3WnJYWXhpVDNJVzFMRld5dUhIQSthdkR5V3lEUVNvQUJaa1ZXelYzVUhqNlBGR2pOVWhkV2JVN1dMRjl6WVgwN0s3dTJGeVY2Ny9mSkNQWDlSMStjdlZGcFl0UFFzT281TkZuRUxybGJSczhkMWc3SnBmWlgvanVYQnRZc2lBNzFpT1A5c1ZxV0hNNVVrV2dkNnhhZE9HRnFpaVNwSk1uK2s1TEw5UFZMWjZCcWRxTE9FRkVMSVVMTS9tVnZJdmQza2J3aVRpVWtaVGI2d3RJL1o4YkFQbEtTUUIveEh1eHk4L0gzY09jOENPb3EyZm5UdExCYVFqNGM0VkVrK01QdUxzSzdzbUZXc1FuUU5SUyt1SFBJUFc0TnY2bnlVajU0dHFlOEZhSXpFaW9CVUQ3NzlzSjlneGl6NjhVUERvNUFySHgzaTJpUzJST2tFR0VVbTkzZllHaTh5OHladFdiOE1zUHZxSmkyQXIwdHZzM3lPSHAzK1dxVE9mVG9ZU3JyTnoyclAiXX0sIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVWQxc1llQUxjQzNuRER6bG92bVVtOVMrSUFhRXdEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRReE5USTBORFphRncweU1qQTRNekF4TlRJME5EWmFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVPL0kzUThGc0VGaWk1b0haQjVIdFplNDZhd1NZeGttVHRtVnBXS2FiNVQ5U0lmem5Wd0wzbjUvaWpMeVE1NGY2YlduTGt4ZXVaeFJmVGRyREhOb2RPcU4yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJTZGpzMHJxTGdFSHZKb2VuMlQwWElSUmlyUzVUQWZCZ05WSFNNRUdEQVdnQlNUbUVtRytUSFcvenJKTTVaZkNQaTI1OVJBOHpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUVDZFJ0RlZFUnBra0Fmajdtd0M3UXUybm9wTVljS0NEYWdES2kxNllKRUxRV0RFeDFkalI5R0Z1MTlRRVJOMFJHU09FZ3pQdW5pZmFVT0dma1lzRmFGOU5BMjdLVkdncEszVGdUbDVBSkJJR0lpS1A4dlNpcUY2S09vc2JUVTNXZUt3VDRtRTN0MXlXY0cvRXhDcVhVY09VbUgyQkZNaDc0YU8yeXA4QUZpUkFLNTFBbFU3TDNXUnZkdGFWTDFycmlpWW5PaDVTclNldlZ2ZWJNZFp4T3pzbDd3R2hwVzZnVmZtMHhtTVBLZENOaHlqVGxYNlV6UkRHcE54VDVUTmIza1lSR3ZpWi9Cc01wVDFNcm5JUVJVVWhMRXo3ZGQ0MzYyWGdSWDFKaTZSdkRLY1FWeFFOZElPVFd5SklEZW5yYnFtdUE0WmVWL09JODZVZjlpUGtqS1VHSmlWaGFZTVd3Z1hTa2ZSeVUzdUFWcGVsTFg3L216bTNQdUpWNVJ5QnNKcU5zdW1zZERTa0ErKzVWaGRPcWk4WXI1Z0kwZ0YzZXA1dGdndlZCS2dHbXBaMmZFRjZCS01UQzRIeWlDYzllMnFlcUxUSU9aUGlNcEptOE42ZnBFWTM3SkVxcVBIZVkxOVdZeGRFVHJZNVhMQ3F0SVRGUlZUTXViSlB5RG5jIl0sIng1dSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0NjgveDV1Iiwiamt1IjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzQ2OC9qa3UiLCJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.u04kxvLdO4YFtqeLDXu0dMaf_RFraL5Oeh3hkavwQBfhQr_XdmOByDn8K8znelDUsEw398-LP8x2xl4SG84FMg" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_1 "eyJraWQiOiIxIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.PjdVrjXaGNpLVW1bZmIQVQFXd65JR6bjbt02SOWUgGAKP0SPrpK4NOt6mmHgtREL8RbQZH_ytHhWZsxJu71KcQ" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_2 "eyJraWQiOiJuZTQ1Sk9WVXFCOGFwelhPbU9fdDY1ekwtU0dkOUtuTVdfT0NtOUNUZUJRIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.FKGb5rBB-FrwjhC3CLe1CmBuhE3yJBqVeOPawojCGRUpXAm4i6bXv1Ynu3_7EkuwYy6z43_hz1_3JEjaFxCh9A" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_3 "eyJraWQiOiJkZjVTckx2SlgzWEI3OHhHa25QZVZDemdXOTZhT2pYSTlfQnFtYkUzV0ljIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.gl8ulx70V61AUXMUfeTfUDGKYAFkvXoGwtwPFg5MsktjY8t1g3D8dkOrMvI_vZHiZNC4rrT3yf6YB-g7T933hQ" #define ADVANCED_TOKEN_SIGNED_WITH_KEY_4 "eyJraWQiOiJPc2lwemxMSjFDQU9VX1duVDJ6dUI0dTMxSWxnRlBzWmZUNGo0cjVxWlVBIiwiandrIjp7Imt0eSI6IkVDIiwieCI6IktPSVItVXpkTDRpOV9uUDM1dVg1UklhZnF3c0FEUkZpTjc0TWNNYTNMVkkiLCJ5IjoiXzB3MzZMb0ZlYVpXTG1jOXYwOHlXNjhEdzFHQWdmNjFmUDRSNUx0TFY1dyIsImNydiI6IlAtMjU2Iiwia2lkIjoiMSIsIng1YyI6WyJNSUlERGpDQ0FYYWdBd0lCQWdJVU5kQlhzUzBmN3c3em9xQlYwMDVlT2VEMkRNZ3dEUVlKS29aSWh2Y05BUUVMQlFBd0tqRVRNQkVHQTFVRUF3d0taMnhsZDJ4M2VXUmZNVEVUTUJFR0ExVUVDaE1LWW1GaVpXeHZkV1Z6ZERBZUZ3MHlNVEE1TVRNeU1UUTVNemhhRncweU1qQTRNamt5TVRRNU16aGFNQ3N4RkRBU0JnTlZCQU1UQzBSaGRtVWdURzl3Y0dWeU1STXdFUVlEVlFRS0V3cGlZV0psYkc5MVpYTjBNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUVLT0lSK1V6ZEw0aTkvblAzNXVYNVJJYWZxd3NBRFJGaU43NE1jTWEzTFZML1REZm91Z1Y1cGxZdVp6Mi9UekpicndQRFVZQ0IvclY4L2hIa3UwdFhuS04yTUhRd0RBWURWUjBUQVFIL0JBSXdBREFUQmdOVkhTVUVEREFLQmdnckJnRUZCUWNEQWpBUEJnTlZIUThCQWY4RUJRTURCNEFBTUIwR0ExVWREZ1FXQkJSL3hBUFZNUlVnU0YySU5yTnNHclg5WmlrU1lEQWZCZ05WSFNNRUdEQVdnQlJabTQya1RDK2FMKzBEVk95U0lESU45U3ZVRWpBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVlFQUhIOEZ0SjRDVmZyU3ZsR3hSa1pIOTFYRks2aWIxMTBiL051OXpJUEcydCtHYUZodkNCdFJmSGhiekY3RkcvbytOTmhiVWZXTG5iUFJlTlF5NDVRYXNxbHJRTURrZ2VDQVpza2VhZHgxTWpyQU44RWJGU21ReFE5ZEtKd1pyWFl4aVQzSVcxTEZXeXVISEErYXZEeVd5RFFTb0FCWmtWV3pWM1VIajZQRkdqTlVoZFdiVTdXTEY5ellYMDdLN3UyRnlWNjcvZkpDUFg5UjErY3ZWRnBZdFBRc09vNU5GbkVMcmxiUnM4ZDFnN0pwZlpYL2p1WEJ0WXNpQTcxaU9QOXNWcVdITTVVa1dnZDZ4YWRPR0ZxaWlTcEpNbitrNUxMOVBWTFo2QnFkcUxPRUZFTElVTE0vbVZ2SXZkM2tid2lUaVVrWlRiNnd0SS9aOGJBUGxLU1FCL3hIdXh5OC9IM2NPYzhDT29xMmZuVHRMQmFRajRjNFZFaytNUHVMc0s3c21GV3NRblFOUlMrdUhQSVBXNE52Nm55VWo1NHRxZThGYUl6RWlvQlVENzc5c0o5Z3hpejY4VVBEbzVBckh4M2kyaVMyUk9rRUdFVW05M2ZZR2k4eTh5WnRXYjhNc1B2cUppMkFyMHR2czN5T0hwMytXcVRPZlRvWVNyck56MnJQIl19LCJ4NWMiOlsiTUlJRERqQ0NBWGFnQXdJQkFnSVVkMXNZZUFMY0MzbkREemxvdm1VbTlTK0lBYUV3RFFZSktvWklodmNOQVFFTEJRQXdLakVUTUJFR0ExVUVBd3dLWjJ4bGQyeDNlV1JmTVRFVE1CRUdBMVVFQ2hNS1ltRmlaV3h2ZFdWemREQWVGdzB5TVRBNU1UUXhOVEkwTkRaYUZ3MHlNakE0TXpBeE5USTBORFphTUNzeEZEQVNCZ05WQkFNVEMwUmhkbVVnVEc5d2NHVnlNUk13RVFZRFZRUUtFd3BpWVdKbGJHOTFaWE4wTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFTy9JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOVNJZnpuVndMM241L2lqTHlRNTRmNmJXbkxreGV1WnhSZlRkckRITm9kT3FOMk1IUXdEQVlEVlIwVEFRSC9CQUl3QURBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFqQVBCZ05WSFE4QkFmOEVCUU1EQjRBQU1CMEdBMVVkRGdRV0JCU2RqczBycUxnRUh2Sm9lbjJUMFhJUlJpclM1VEFmQmdOVkhTTUVHREFXZ0JTVG1FbUcrVEhXL3pySk01WmZDUGkyNTlSQTh6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FZRUFFQ2RSdEZWRVJwa2tBZmo3bXdDN1F1Mm5vcE1ZY0tDRGFnREtpMTZZSkVMUVdERXgxZGpSOUdGdTE5UUVSTjBSR1NPRWd6UHVuaWZhVU9HZmtZc0ZhRjlOQTI3S1ZHZ3BLM1RnVGw1QUpCSUdJaUtQOHZTaXFGNktPb3NiVFUzV2VLd1Q0bUUzdDF5V2NHL0V4Q3FYVWNPVW1IMkJGTWg3NGFPMnlwOEFGaVJBSzUxQWxVN0wzV1J2ZHRhVkwxcnJpaVluT2g1U3JTZXZWdmViTWRaeE96c2w3d0docFc2Z1ZmbTB4bU1QS2RDTmh5alRsWDZVelJER3BOeFQ1VE5iM2tZUkd2aVovQnNNcFQxTXJuSVFSVVVoTEV6N2RkNDM2MlhnUlgxSmk2UnZES2NRVnhRTmRJT1RXeUpJRGVucmJxbXVBNFplVi9PSTg2VWY5aVBraktVR0ppVmhhWU1Xd2dYU2tmUnlVM3VBVnBlbExYNy9tem0zUHVKVjVSeUJzSnFOc3Vtc2REU2tBKys1VmhkT3FpOFlyNWdJMGdGM2VwNXRnZ3ZWQktnR21wWjJmRUY2QktNVEM0SHlpQ2M5ZTJxZXFMVElPWlBpTXBKbThONmZwRVkzN0pFcXFQSGVZMTlXWXhkRVRyWTVYTENxdElURlJWVE11YkpQeURuYyJdLCJ4NXUiOiJodHRwczovL2xvY2FsaG9zdDo3NDY4L3g1dSIsImprdSI6Imh0dHBzOi8vbG9jYWxob3N0Ojc0Njgvamt1IiwidHlwIjoiSldUIiwiYWxnIjoiRVMyNTYifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.6ULy8B5R__8Ie8Rah47jE4dkZJXwJkrthfYFQAMrPzgvbIKVOLchujW7C7u_k_fojDsBXeXHGcND5Fdaxzxjlw" #define ADVANCED_NESTED_TOKEN_SE_SIGNED_WITH_KEY_2 "eyJqd2siOnsia3R5IjoiRUMiLCJ4IjoiT19JM1E4RnNFRmlpNW9IWkI1SHRaZTQ2YXdTWXhrbVR0bVZwV0thYjVUOCIsInkiOiJVaUg4NTFjQzk1LWY0b3k4a09lSC1tMXB5NU1Ycm1jVVgwM2F3eHphSFRvIiwiY3J2IjoiUC0yNTYiLCJraWQiOiJuZTQ1Sk9WVXFCOGFwelhPbU9fdDY1ekwtU0dkOUtuTVdfT0NtOUNUZUJRIiwieDVjIjpbIk1JSUREakNDQVhhZ0F3SUJBZ0lVZDFzWWVBTGNDM25ERHpsb3ZtVW05UytJQWFFd0RRWUpLb1pJaHZjTkFRRUxCUUF3S2pFVE1CRUdBMVVFQXd3S1oyeGxkMngzZVdSZk1URVRNQkVHQTFVRUNoTUtZbUZpWld4dmRXVnpkREFlRncweU1UQTVNVFF4TlRJME5EWmFGdzB5TWpBNE16QXhOVEkwTkRaYU1Dc3hGREFTQmdOVkJBTVRDMFJoZG1VZ1RHOXdjR1Z5TVJNd0VRWURWUVFLRXdwaVlXSmxiRzkxWlhOME1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRU8vSTNROEZzRUZpaTVvSFpCNUh0WmU0NmF3U1l4a21UdG1WcFdLYWI1VDlTSWZ6blZ3TDNuNS9pakx5UTU0ZjZiV25Ma3hldVp4UmZUZHJESE5vZE9xTjJNSFF3REFZRFZSMFRBUUgvQkFJd0FEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFQQmdOVkhROEJBZjhFQlFNREI0QUFNQjBHQTFVZERnUVdCQlNkanMwcnFMZ0VIdkpvZW4yVDBYSVJSaXJTNVRBZkJnTlZIU01FR0RBV2dCU1RtRW1HK1RIVy96ckpNNVpmQ1BpMjU5UkE4ekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBWUVBRUNkUnRGVkVScGtrQWZqN213QzdRdTJub3BNWWNLQ0RhZ0RLaTE2WUpFTFFXREV4MWRqUjlHRnUxOVFFUk4wUkdTT0VnelB1bmlmYVVPR2ZrWXNGYUY5TkEyN0tWR2dwSzNUZ1RsNUFKQklHSWlLUDh2U2lxRjZLT29zYlRVM1dlS3dUNG1FM3QxeVdjRy9FeENxWFVjT1VtSDJCRk1oNzRhTzJ5cDhBRmlSQUs1MUFsVTdMM1dSdmR0YVZMMXJyaWlZbk9oNVNyU2V2VnZlYk1kWnhPenNsN3dHaHBXNmdWZm0weG1NUEtkQ05oeWpUbFg2VXpSREdwTnhUNVROYjNrWVJHdmlaL0JzTXBUMU1ybklRUlVVaExFejdkZDQzNjJYZ1JYMUppNlJ2REtjUVZ4UU5kSU9UV3lKSURlbnJicW11QTRaZVYvT0k4NlVmOWlQa2pLVUdKaVZoYVlNV3dnWFNrZlJ5VTN1QVZwZWxMWDcvbXptM1B1SlY1UnlCc0pxTnN1bXNkRFNrQSsrNVZoZE9xaThZcjVnSTBnRjNlcDV0Z2d2VkJLZ0dtcFoyZkVGNkJLTVRDNEh5aUNjOWUycWVxTFRJT1pQaU1wSm04TjZmcEVZMzdKRXFxUEhlWTE5V1l4ZEVUclk1WExDcXRJVEZSVlRNdWJKUHlEbmMiXX0sImtpZCI6Im5lNDVKT1ZVcUI4YXB6WE9tT190NjV6TC1TR2Q5S25NV19PQ205Q1RlQlEiLCJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJFQ0RILUVTK0ExMjhLVyIsImVwayI6eyJrdHkiOiJFQyIsIngiOiJGS3pXWTRVQWM4V04taGRURG5MSXZwOHVDLXlnVGVsbzg5bGVGMlFnUFRvIiwieSI6IkhJMUlCWk80bnQtenIzTWtNNmZNMGp2VC1NdFMxZjM3WW9IRklpNUFRTm8iLCJjcnYiOiJQLTI1NiJ9LCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.-l-XNKt-YghvBJRkrVkfOk4pMecbY1NVnLtWjUjzLBkYPlNTsGJhhA.W2GeMAwSQcmpnrwYM707eA.fCoZXpzRBSA0-Ds_g9T7kIl8dhqVlgeWrZDxGTnzpgAmQklZss2gQ3YP5j8wo8wqjB7fC1M8oPFc9HP_OHfy0iCUdy9Nc2iinMtXHiS-n9TB3s5pkAA66fd4FCzJewB4YzSprLdYo_knQhmbOhQ0bgmPR489nU42yYp8Q8ssJAo3Ksz4mGE9edbpYXiKansQiXYzqOJglIlef-htndnUj5gEKEQs_sfu0NM9Qm7nqJuHzPC5b5uaiXAdkNQaWue9V5Lluse6hcSYDPcBmAiwfSqNTauP4p__srYfu9aEkCnsk8PsRkn-IWnqVZHOlc7K91xHVGknxQJPCFNf03d1ybPxIAU8-Ms1xAf3F4R1RXKYweZTeqzCjcRGQ52UD7bMTkkwAlawO8uazw3KDY41kDaNxQWhvGBKuO4ybOE-dBsRvvZahiHqX95wfJOgsTSwSAKwmjcda0xAYuqn_sTVPWsLI3q1yMkXo_8YbQr6PYQf66h9cnAkHfQPV2QqHER7KNzKEscmbAI2LUCpxZIqZYJswwtRGCQaJB50-1RV-_HUyx3iW-6OBjjVFCMntpYjqzzRdT-wlDwy3VoBs0cWkMpuovBxeBRwg0j3gXN4aWcUL7dKqecz_PE-qput5iAHPmuaUGZh24bZ-ekxapBvUFb7iOvdavrpn7A1g4NezoGe5N-OySzv49uSJvsNy6ks0Q9ZmgSSbyiv4FwYx0tZZZT8L_59yYcBaeGbU-yYlUVPmACEgqY9whpxZjuea57bvr8IFlwcYxmxEFCrtrc1vQMJs5oEFNxyO9HIkiWT95SWsDOc7a8F_S_IidiAm4Z7bitAxiSN-6wgqGLzF4cgUoylV0dsBzncfpHiKbM7gJJAeN_RYS8pkfdUqjiI4Qbz2HpDJLHBgFBx5FqEQcB-P9enikL3Tvi5NzYH1k9IqnbZk3spLoAHUyGxU85izZ6_fQpunlO53cpwQriFArV3s51xfYyXxbsKYfGx523YA7A-AHASjtG-Kx863GiRAxN2oxBQIZYFcG0iMTmy6Bv9yQlGjYXROTtme11iqzQrhfiVHMZKb65MzjIpU7EvwlhWrOmUZZWiG4TbwfywPlnAZUB9yCcveGTC27u9C1NF4xF95bfN8ngOBK3rYEvRfRqy6pdNDHCQKs-sUv2T1K-wh6bIqUa30U4nBopCX1oJju3ZHltZdCZZEhzqIEkG3T46UaC9xqGTwxijfjl38YLGgZ9OLeI3_Y4U7W3kAWdyEI6PdOv_wknpPWkNCDlb5Scyzjpr45rafpONg0tkZHKo18JQW_O0xjd0hnyl1l7N724KsiWKm-PPX76_4pyWXQ-hsCaST6xSedJn5dWV6J_MA0m6K7I69_-tE1dPGvG2TmbREemPHoT7mCwA-Wg1o1FXBj9OrKqTqxWKCV4JsBZhWzQt3ZHNeTlPRqN16bZE_tIDEwnXDlJnAdWtl8oHMw09iK7OxtLeJr9WwykwBQKrAVGbzP45t7qMPbvbFfrkalMmUzZmDIhXO_viatM6EwAVRUKHUywhMExS9zRdDKm291MGhM8kMQmArfYG7bUmx065xFRq-z77BHHL4QFu5ph9I-n6po366kL7vCPdLpotyOA6e-TSO3bQSVUto9mtY3jWNJr5VdijSWnDB6KZ3uf0HPC8m_40_Wpi3UbbSAzwG6X2sUw2CwmrhFxkLjINWI6LmqBujSrnhdQ0DdPahl_CfEDnZfBECG7_gw0SeBHpBli99N1sqVGoB8-7_ps-9GuDdqf3PR8MMWO6J8rbecQzWd0zvAaml8nmvZVBxOA__AHCarC7fn6gdaFMppEhKVgQuxEYUgnvS6_V6wycn1swxMDA9AhgJyZbhEH9Hwdd3w8MKmxiYKS8HOwjeJw7hJCeVLjy4dO9BhMvuglkAgNeGGEMKeYtCSQ84xBicWSyEqYF66eD1hWGD3a8a4NsmucbLcyO5Azn57ls-HTzVdh1I2dm02tUIuAF8xozIS1Zr17zbkUO3xjgWiVSUhnoAOJMaXCTHjXJfM9K-sU4-ElMKa4e_FxlBiPdTuzJe6E6ya3Eru-KPeN4cKayV2tMY2astHJLWOrvAMgR25wtpgXMNbJk6QtuoNKrDe-m8lb4duM3iG9gTT7dYFrFoUIZug6s24f4Q2GAtWzpTTBv1na_EsT38-feaUyEnHYgpz9_cvIr7bEXrlosgQIM2WKgk4CPBQn9-Xt2FBakuVlGr2IwveyDxvoOsHBY5zpkRV9sY-LPgHDEcjT1Hoa6r0TmxTE96tI_iKQxyd2U3REVATguVS9ntjDRwUTDwcL8Ve43tKyyD29chC6P32MKzff0XsqGLioPd1G4T2N7nw9ReOmXTH2elkBnnqPf85rz1XXmZzZcx9xPIgaeLpIaYrizahWeUlhRDa3i5PaZ_U-RjVO9Pcs02caitDx24Tzo3LqbZ7ylUEHKzO04npIo8cl7Sr8M0cXL90WG3VccwoJHP_P--TexUDxsWA3_jfydxAZmZ50AElbByrlaaIqBBbH7J5o.oIdhT5DGgVLYY0BeC2N5sA" #define TOKEN "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_HEADER "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ij.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_HEADER_B64 ";error;.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_CLAIMS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cn.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_CLAIMS_B64 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.;error;.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQeyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_UNSECURE "eyJhbGciOiJub25lIn0.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ." #define TOKEN_ENC "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_ENC_INVALID_HEADER_B64 ";error;.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_ENC_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_ENC_INVALID_SIGNATURE "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4wRWJ.94p-hjUgcWGiJsQ8TnnKtQ" START_TEST(test_rhonabwy_init) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_sign_alg) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_UNKNOWN); ck_assert_int_eq(r_jwt_set_sign_alg(NULL, R_JWA_ALG_ES256), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_ES256), RHN_OK); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_ES256); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS512), RHN_OK); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_RS512); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_enc_alg) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_get_enc_alg(jwt), R_JWA_ALG_UNKNOWN); ck_assert_int_eq(r_jwt_set_enc_alg(NULL, R_JWA_ALG_RSA1_5), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_get_enc_alg(jwt), R_JWA_ALG_RSA1_5); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_ECDH_ES), RHN_OK); ck_assert_int_eq(r_jwt_get_enc_alg(jwt), R_JWA_ALG_ECDH_ES); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_header) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_header_str_value(NULL, "key", "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, NULL, "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "key", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_header_int_value(NULL, "key", 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_int_value(jwt, NULL, 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_int_value(jwt, "key", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_header_json_t_value(NULL, "key", j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, NULL, j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, "key", j_value), RHN_OK); json_decref(j_value); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_get_header) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_result; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_header_int_value(jwt, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, "keyjson", j_value), RHN_OK); ck_assert_str_eq("value", r_jwt_get_header_str_value(jwt, "keystr")); ck_assert_int_eq(42, r_jwt_get_header_int_value(jwt, "keyint")); ck_assert_int_eq(json_equal(j_value, (j_result = r_jwt_get_header_json_t_value(jwt, "keyjson"))) , 1); ck_assert_ptr_eq(NULL, r_jwt_get_header_str_value(jwt, "error")); ck_assert_int_eq(0, r_jwt_get_header_int_value(jwt, "error")); ck_assert_ptr_eq(NULL, r_jwt_get_header_json_t_value(jwt, "error")); json_decref(j_value); json_decref(j_result); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_full_header_error) { jwt_t * jwt; json_t * j_header; j_header = json_pack("{ssss}", "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", "error"); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, j_header), RHN_ERROR_PARAM); r_jwt_free(jwt); json_decref(j_header); j_header = json_pack("{ssss}", "alg", "error", "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, j_header), RHN_ERROR_PARAM); r_jwt_free(jwt); json_decref(j_header); j_header = json_pack("{ss}", "alg", "error"); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, j_header), RHN_ERROR_PARAM); r_jwt_free(jwt); json_decref(j_header); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, NULL), RHN_ERROR_PARAM); r_jwt_free(jwt); j_header = json_pack("{ssss}", "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); ck_assert_int_eq(r_jwt_set_full_header_json_t(NULL, j_header), RHN_ERROR_PARAM); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_set_full_header) { jwt_t * jwt; json_t * j_header = json_pack("{sssisossss}", "str", JWT_CLAIM_AUD1, "int", JWT_CLAIM_AGE, "obj", json_true(), "alg", r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "enc", r_jwa_enc_to_str(R_JWA_ENC_A256GCM)); char * str_header = json_dumps(j_header, JSON_COMPACT); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, j_header), RHN_OK); ck_assert_str_eq(r_jwt_get_header_str_value(jwt, "str"), JWT_CLAIM_AUD1); ck_assert_int_eq(r_jwt_get_header_int_value(jwt, "int"), JWT_CLAIM_AGE); ck_assert_ptr_eq(r_jwt_get_header_json_t_value(jwt, "obj"), json_true()); ck_assert_int_eq(r_jwt_get_enc_alg(jwt), R_JWA_ALG_RSA_OAEP_256); ck_assert_int_eq(r_jwt_get_enc(jwt), R_JWA_ENC_A256GCM); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_str(jwt, str_header), RHN_OK); ck_assert_str_eq(r_jwt_get_header_str_value(jwt, "str"), JWT_CLAIM_AUD1); ck_assert_int_eq(r_jwt_get_header_int_value(jwt, "int"), JWT_CLAIM_AGE); ck_assert_ptr_eq(r_jwt_get_header_json_t_value(jwt, "obj"), json_true()); ck_assert_int_eq(r_jwt_get_enc_alg(jwt), R_JWA_ALG_RSA_OAEP_256); ck_assert_int_eq(r_jwt_get_enc(jwt), R_JWA_ENC_A256GCM); r_jwt_free(jwt); o_free(str_header); json_decref(j_header); j_header = json_pack("{sssisoss}", "str", JWT_CLAIM_AUD1, "int", JWT_CLAIM_AGE, "obj", json_true(), "alg", r_jwa_alg_to_str(R_JWA_ALG_RS256)); str_header = json_dumps(j_header, JSON_COMPACT); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_t(jwt, j_header), RHN_OK); ck_assert_str_eq(r_jwt_get_header_str_value(jwt, "str"), JWT_CLAIM_AUD1); ck_assert_int_eq(r_jwt_get_header_int_value(jwt, "int"), JWT_CLAIM_AGE); ck_assert_ptr_eq(r_jwt_get_header_json_t_value(jwt, "obj"), json_true()); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_RS256); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_header_json_str(jwt, str_header), RHN_OK); ck_assert_str_eq(r_jwt_get_header_str_value(jwt, "str"), JWT_CLAIM_AUD1); ck_assert_int_eq(r_jwt_get_header_int_value(jwt, "int"), JWT_CLAIM_AGE); ck_assert_ptr_eq(r_jwt_get_header_json_t_value(jwt, "obj"), json_true()); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_RS256); r_jwt_free(jwt); o_free(str_header); json_decref(j_header); } END_TEST START_TEST(test_rhonabwy_get_full_header) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_header = json_pack("{sssisO}", "keystr", "value", "keyint", 42, "keyjson", j_value), * j_result; ck_assert_ptr_ne(j_header, NULL); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_header_int_value(jwt, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, "keyjson", j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(json_equal(j_header, (j_result = r_jwt_get_full_header_json_t(jwt))) , 1); json_decref(j_value); json_decref(j_header); json_decref(j_result); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_claim) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(NULL, "key", "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, NULL, "value"), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "key", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(NULL, "key", 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, NULL, 42), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "key", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_json_t_value(NULL, "key", j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, NULL, j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "key", NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "key", j_value), RHN_OK); json_decref(j_value); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_get_claim) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_result; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "keyjson", j_value), RHN_OK); ck_assert_str_eq("value", r_jwt_get_claim_str_value(jwt, "keystr")); ck_assert_int_eq(42, r_jwt_get_claim_int_value(jwt, "keyint")); ck_assert_int_eq(json_equal(j_value, (j_result = r_jwt_get_claim_json_t_value(jwt, "keyjson"))) , 1); ck_assert_ptr_eq(NULL, r_jwt_get_claim_str_value(jwt, "error")); ck_assert_int_eq(0, r_jwt_get_claim_int_value(jwt, "error")); ck_assert_ptr_eq(NULL, r_jwt_get_claim_json_t_value(jwt, "error")); json_decref(j_value); json_decref(j_result); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_full_claims) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_str_eq("value", r_jwt_get_claim_str_value(jwt, "keystr")); ck_assert_int_eq(r_jwt_set_full_claims_json_t(NULL, j_value), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, NULL), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_ptr_eq(NULL, r_jwt_get_claim_str_value(jwt, "keystr")); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); json_decref(j_value); json_decref(j_claims); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_full_claims_str) { jwt_t * jwt; char str_value[] = "{\"str\":\"grut\",\"int\":42,\"obj\":true}"; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_str_eq("value", r_jwt_get_claim_str_value(jwt, "keystr")); ck_assert_int_eq(r_jwt_set_full_claims_json_str(jwt, str_value), RHN_OK); ck_assert_ptr_eq(NULL, r_jwt_get_claim_str_value(jwt, "keystr")); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); json_decref(j_value); json_decref(j_claims); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_get_full_claims) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims, * j_expected = json_pack("{sssisO}", "keystr", "value", "keyint", 42, "keyjson", j_value); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "keyint", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "keyjson", j_value), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_expected)); json_decref(j_value); json_decref(j_claims); json_decref(j_expected); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_append_claims) { jwt_t * jwt; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims, * j_expected_1 = json_pack("{sssi}", "keystr", "value", "keyint", 42), * j_expected_2 = json_pack("{sssisO}", "keystr", "value", "keyint", 42, "keyjson", j_value); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "keystr", "value"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "keyint", 42), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_expected_1)); json_decref(j_claims); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "keyjson", j_value), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_expected_2)); json_decref(j_value); json_decref(j_claims); json_decref(j_expected_1); json_decref(j_expected_2); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_sign_keys) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_pubkey_rsa, jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(NULL, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_sign_jwks) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; jwks_t * jwks_pubkey, * jwks_privkey, * jwks; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_rsa), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(0, r_jwks_size(jwt->jwks_privkey_sign)); ck_assert_int_eq(0, r_jwks_size(jwt->jwks_pubkey_sign)); ck_assert_int_eq(r_jwt_add_sign_jwks(jwt, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_int_eq(2, r_jwks_size(jwt->jwks_privkey_sign)); ck_assert_int_eq(2, r_jwks_size(jwt->jwks_pubkey_sign)); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_add_sign_keys_by_content) { jwt_t * jwt; jwk_t * jwk_priv, * jwk_pub; jwks_t * jwks; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t g_privkey; gnutls_pubkey_t g_pubkey; #endif json_t * j_privkey, * j_pubkey; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_rsa_str), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(g_privkey = r_jwk_export_to_gnutls_privkey(jwk_priv), NULL); ck_assert_ptr_ne(g_pubkey = r_jwk_export_to_gnutls_pubkey(jwk_pub, 0), NULL); #endif ck_assert_ptr_ne(j_privkey = r_jwk_export_to_json_t(jwk_priv), NULL); ck_assert_ptr_ne(j_pubkey = r_jwk_export_to_json_t(jwk_pub), NULL); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_sign_keys_json_str(jwt, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_sign_keys_json_t(jwt, j_privkey, j_pubkey), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_sign_keys_pem_der(jwt, R_FORMAT_PEM, rsa_2048_priv, sizeof(rsa_2048_priv), rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_sign_key_symmetric(jwt, symmetric_key, sizeof(symmetric_key)), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwt_add_sign_keys_gnutls(jwt, g_privkey, g_pubkey), RHN_OK); jwks = r_jwt_get_sign_jwks_privkey(jwt); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_sign_jwks_pubkey(jwt); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); #endif r_jwt_free(jwt); #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_deinit(g_privkey); gnutls_pubkey_deinit(g_pubkey); #endif json_decref(j_privkey); json_decref(j_pubkey); r_jwk_free(jwk_priv); r_jwk_free(jwk_pub); } END_TEST START_TEST(test_rhonabwy_set_enc_keys) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_pubkey_rsa, jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(NULL, jwk_pubkey_ecdsa, jwk_privkey_ecdsa), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, NULL), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_enc_jwks) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_ecdsa, * jwk_pubkey_rsa, * jwk_privkey_rsa; jwks_t * jwks_pubkey, * jwks_privkey, * jwks; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_pubkey), RHN_OK); ck_assert_int_eq(r_jwks_init(&jwks_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_pubkey, jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwks_privkey, jwk_privkey_rsa), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(0, r_jwks_size(jwt->jwks_privkey_enc)); ck_assert_int_eq(0, r_jwks_size(jwt->jwks_pubkey_enc)); ck_assert_int_eq(r_jwt_add_enc_jwks(jwt, jwks_privkey, jwks_pubkey), RHN_OK); ck_assert_int_eq(2, r_jwks_size(jwt->jwks_privkey_enc)); ck_assert_int_eq(2, r_jwks_size(jwt->jwks_pubkey_enc)); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_privkey_rsa); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_add_enc_keys_by_content) { jwt_t * jwt; jwk_t * jwk_priv, * jwk_pub; jwks_t * jwks; #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_t g_privkey; gnutls_pubkey_t g_pubkey; #endif json_t * j_privkey, * j_pubkey; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_priv), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_priv, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_rsa_str), RHN_OK); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_ptr_ne(g_privkey = r_jwk_export_to_gnutls_privkey(jwk_priv), NULL); ck_assert_ptr_ne(g_pubkey = r_jwk_export_to_gnutls_pubkey(jwk_pub, 0), NULL); #endif ck_assert_ptr_ne(j_privkey = r_jwk_export_to_json_t(jwk_priv), NULL); ck_assert_ptr_ne(j_pubkey = r_jwk_export_to_json_t(jwk_pub), NULL); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(0, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_enc_keys_json_str(jwt, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(1, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_enc_keys_json_t(jwt, j_privkey, j_pubkey), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(2, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_enc_keys_pem_der(jwt, R_FORMAT_PEM, rsa_2048_priv, sizeof(rsa_2048_priv), rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(3, r_jwks_size(jwks)); r_jwks_free(jwks); ck_assert_int_eq(r_jwt_add_enc_key_symmetric(jwt, symmetric_key, sizeof(symmetric_key)), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(4, r_jwks_size(jwks)); r_jwks_free(jwks); #if GNUTLS_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwt_add_enc_keys_gnutls(jwt, g_privkey, g_pubkey), RHN_OK); jwks = r_jwt_get_enc_jwks_privkey(jwt); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); jwks = r_jwt_get_enc_jwks_pubkey(jwt); ck_assert_int_eq(5, r_jwks_size(jwks)); r_jwks_free(jwks); #endif r_jwt_free(jwt); #if GNUTLS_VERSION_NUMBER >= 0x030600 gnutls_privkey_deinit(g_privkey); gnutls_pubkey_deinit(g_pubkey); #endif json_decref(j_privkey); json_decref(j_pubkey); r_jwk_free(jwk_priv); r_jwk_free(jwk_pub); } END_TEST START_TEST(test_rhonabwy_set_claims) { jwt_t * jwt; time_t exp; time(&exp); exp+=JWT_CLAIM_EXP; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, exp, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_2, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_2, R_JWT_CLAIM_NOP), RHN_OK); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_invalid_claims) { jwt_t * jwt; json_t * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "iss", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "sub", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "aud", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "exp", "42"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "nbf", "42"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iat", "42"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "jti", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "amr", "42"), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "typ", 42), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "cty", 42), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_CTY, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); j_claims = json_pack("[si]", "42", 42); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "amr", j_claims), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_claims); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_validate_claims) { jwt_t * jwt; time_t now; json_t * j_aud; time(&now); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_STR, "scope", NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JSN, "verified", NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_CTY, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iss", JWT_CLAIM_ISS), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "sub", JWT_CLAIM_SUB), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_ptr_ne(NULL, j_aud = json_pack("[ss]", JWT_CLAIM_AUD1, JWT_CLAIM_AUD2)); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "aud", j_aud), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD2, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD3, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_aud); ck_assert_ptr_ne(NULL, j_aud = json_pack("[si]", JWT_CLAIM_AUD1, 42)); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "aud", j_aud), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_aud); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "aud", JWT_CLAIM_AUD1), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "jti", JWT_CLAIM_JTI), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "exp", (now+JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, now+1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, (now+JWT_CLAIM_EXP+JWT_CLAIM_EXP), R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "nbf", (now-JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, now-1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, (now-JWT_CLAIM_NBF-JWT_CLAIM_NBF), R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "iat", (now-JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, now-1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, (now-JWT_CLAIM_IAT-JWT_CLAIM_IAT), R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "scope", JWT_CLAIM_SCOPE), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_STR, "scope", "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "age", JWT_CLAIM_AGE), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE-1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "verified", JWT_CLAIM_VERIFIED), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JSN, "verified", json_null(), R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "typ", JWT_CLAIM_TYP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_set_header_str_value(jwt, "cty", JWT_CLAIM_CTY), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_CTY, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_ptr_ne(NULL, j_aud = json_pack("[ss]", JWT_CLAIM_AMR_1, JWT_CLAIM_AMR_2)); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "amr", j_aud), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AMR, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_aud); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_SUB, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JTI, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_EXP, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_NBF, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_IAT, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_STR, "scope", NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_JSN, "verified", NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_TYP, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_SUB, NULL, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_JTI, NULL, R_JWT_CLAIM_EXP, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_NBF, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_IAT, R_JWT_CLAIM_PRESENT, R_JWT_CLAIM_STR, "scope", NULL, R_JWT_CLAIM_JSN, "verified", NULL, R_JWT_CLAIM_AMR, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, "error", R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, R_JWT_CLAIM_NOW, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_STR, "error", JWT_CLAIM_SCOPE, R_JWT_CLAIM_AMR, JWT_CLAIM_AMR_1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_validate_claims_aud_array) { jwt_t * jwt; json_t * j_aud; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iss", JWT_CLAIM_ISS), RHN_OK); ck_assert_ptr_ne(NULL, j_aud = json_pack("[ss]", JWT_CLAIM_AUD1, JWT_CLAIM_AUD2)); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "aud", j_aud), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD2, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD3, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_aud); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_AUD, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iss", JWT_CLAIM_ISS), RHN_OK); ck_assert_ptr_ne(NULL, j_aud = json_pack("[si]", JWT_CLAIM_AUD1, 42)); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "aud", j_aud), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD3, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); json_decref(j_aud); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, NULL, R_JWT_CLAIM_AUD, NULL, R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_AUD, "error", R_JWT_CLAIM_NOP), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_set_properties_error) { jwt_t * jwt; jwk_t * jwk; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwt_set_properties(jwt, RHN_OPT_PAYLOAD, PAYLOAD, o_strlen(PAYLOAD), RHN_OPT_NONE), RHN_ERROR_PARAM); r_jwt_free(jwt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_set_properties) { jwt_t * jwt; jwk_t * jwk; const unsigned char * key_iv; size_t key_iv_len; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwt_set_properties(jwt, RHN_OPT_HEADER_INT_VALUE, "int", CLAIM_INT, RHN_OPT_HEADER_RHN_INT_VALUE, "rhn_int", (rhn_int_t)CLAIM_INT, RHN_OPT_HEADER_STR_VALUE, "str", CLAIM_STR, RHN_OPT_HEADER_JSON_T_VALUE, "json", json_true(), RHN_OPT_CLAIM_INT_VALUE, "int", CLAIM_INT, RHN_OPT_CLAIM_RHN_INT_VALUE, "rhn_int", (rhn_int_t)CLAIM_INT, RHN_OPT_CLAIM_STR_VALUE, "str", CLAIM_STR, RHN_OPT_CLAIM_JSON_T_VALUE, "json", json_true(), RHN_OPT_ENC_ALG, R_JWA_ALG_RSA1_5, RHN_OPT_ENC, R_JWA_ENC_A256GCM, RHN_OPT_SIG_ALG, R_JWA_ALG_RS256, RHN_OPT_CIPHER_KEY, cypher_key, sizeof(cypher_key), RHN_OPT_IV, iv, sizeof(iv), RHN_OPT_ENCRYPT_KEY_JWK, jwk, RHN_OPT_DECRYPT_KEY_JWK, jwk, RHN_OPT_SIGN_KEY_JWK, jwk, RHN_OPT_VERIFY_KEY_JWK, jwk, RHN_OPT_NONE), RHN_OK); ck_assert_int_eq(CLAIM_INT, r_jwt_get_header_int_value(jwt, "int")); ck_assert_int_eq(CLAIM_INT, r_jwt_get_header_int_value(jwt, "rhn_int")); ck_assert_str_eq(CLAIM_STR, r_jwt_get_header_str_value(jwt, "str")); ck_assert_ptr_eq(json_true(), r_jwt_get_header_json_t_value(jwt, "json")); ck_assert_int_eq(CLAIM_INT, r_jwt_get_claim_int_value(jwt, "int")); ck_assert_int_eq(CLAIM_INT, r_jwt_get_claim_int_value(jwt, "rhn_int")); ck_assert_str_eq(CLAIM_STR, r_jwt_get_claim_str_value(jwt, "str")); ck_assert_ptr_eq(json_true(), r_jwt_get_claim_json_t_value(jwt, "json")); ck_assert_int_eq(R_JWA_ALG_RSA1_5, r_jwt_get_enc_alg(jwt)); ck_assert_int_eq(R_JWA_ENC_A256GCM, r_jwt_get_enc(jwt)); ck_assert_int_eq(R_JWA_ALG_RS256, r_jwt_get_sign_alg(jwt)); ck_assert_ptr_ne(NULL, key_iv = r_jwt_get_enc_cypher_key(jwt, &key_iv_len)); ck_assert_int_eq(sizeof(cypher_key), key_iv_len); ck_assert_int_eq(0, memcmp(key_iv, cypher_key, key_iv_len)); ck_assert_ptr_ne(NULL, key_iv = r_jwt_get_enc_iv(jwt, &key_iv_len)); ck_assert_int_eq(sizeof(iv), key_iv_len); ck_assert_int_eq(0, memcmp(key_iv, iv, key_iv_len)); ck_assert_int_eq(1, r_jwks_size(jwt->jwks_privkey_sign)); ck_assert_int_eq(1, r_jwks_size(jwt->jwks_pubkey_sign)); ck_assert_int_eq(1, r_jwks_size(jwt->jwks_privkey_enc)); ck_assert_int_eq(1, r_jwks_size(jwt->jwks_pubkey_enc)); r_jwt_free(jwt); r_jwk_free(jwk); } END_TEST START_TEST(test_rhonabwy_copy) { jwt_t * jwt, * jwt_copy; char * token = NULL, * token_copy; time_t now; time(&now); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iss", JWT_CLAIM_ISS), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "sub", JWT_CLAIM_SUB), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "aud", JWT_CLAIM_AUD1), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "jti", JWT_CLAIM_JTI), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "exp", (now+JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "nbf", (now-JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "iat", (now-JWT_CLAIM_EXP)), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "scope", JWT_CLAIM_SCOPE), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_int_value(jwt, "age", JWT_CLAIM_AGE), RHN_OK); ck_assert_int_eq(r_jwt_set_claim_json_t_value(jwt, "verified", JWT_CLAIM_VERIFIED), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys_json_str(jwt, jwk_privkey_rsa_str, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_key_symmetric(jwt, (const unsigned char *)symmetric_key, sizeof(symmetric_key)), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_HS256), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0)), NULL); ck_assert_ptr_ne((jwt_copy = r_jwt_copy(jwt)), NULL); ck_assert_ptr_ne((token_copy = r_jwt_serialize_nested(jwt_copy, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0)), NULL); ck_assert_int_eq(r_jwt_parse(jwt_copy, token, 0), RHN_OK); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt_copy, NULL, 0, NULL, 0), RHN_OK); o_free(token); o_free(token_copy); r_jwt_free(jwt); r_jwt_free(jwt_copy); } END_TEST START_TEST(test_rhonabwy_set_enc_cypher_key_iv) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); char * token, ** token_split; ck_assert_int_eq(r_jwt_set_claim_str_value(jwt, "iss", JWT_CLAIM_ISS), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_cypher_key(jwt, cypher_key, sizeof(cypher_key)), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_iv(jwt, iv, sizeof(iv)), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys_json_str(jwt, NULL, pubkey), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_encrypted(jwt, NULL, 0)), NULL); ck_assert_int_eq(split_string(token, ".", &token_split), 5); ck_assert_str_eq("AxY8DCtDaGlsbGljb3RoZQ", token_split[2]); ck_assert_str_eq("FgA-dGeGpV_KbHo21rm9i0cLuAKdqhEm6nXaPSrRdAw", token_split[3]); free_string_array(token_split); o_free(token); r_jwt_free(jwt); } END_TEST #if GNUTLS_VERSION_NUMBER >= 0x030600 && defined(R_WITH_CURL) static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } int callback_x5u_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_string_body_response(response, 200, (const char *)advanced_cert_pem_3); return U_CALLBACK_CONTINUE; } int callback_jku_ecdsa_crt (const struct _u_request * request, struct _u_response * response, void * user_data) { ulfius_set_response_properties(response, U_OPT_STATUS, 200, U_OPT_HEADER_PARAMETER, "Content-Type", "application/json", U_OPT_STRING_BODY, advanced_jku_4, U_OPT_NONE); return U_CALLBACK_CONTINUE; } START_TEST(test_rhonabwy_advanced_parse) { jwk_t * jwk_pub, * jwk_priv, * jwk_pubkey_1; jwt_t * jwt; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_priv), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_priv, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_1), RHN_OK); ck_assert_int_eq(r_jwk_import_from_pem_der(jwk_pubkey_1, R_X509_TYPE_CERTIFICATE, R_FORMAT_PEM, advanced_cert_pem_1, sizeof(advanced_cert_pem_1)), RHN_OK); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_X5U|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 2); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); r_jwt_free(jwt); // Attack vectors tested ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_HEADER_X5C|R_PARSE_HEADER_X5U|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 3); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_1, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5U|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 3); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_2, R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C|R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 3); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_3, R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); // This is dangerous ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C|R_PARSE_HEADER_X5U, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 3); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_TOKEN_SIGNED_WITH_KEY_4, R_PARSE_HEADER_JKU, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pub), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); #if GNUTLS_VERSION_NUMBER >= 0x030600 && NETTLE_VERSION_NUMBER >= 0x030600 ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, ADVANCED_NESTED_TOKEN_SE_SIGNED_WITH_KEY_2, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_priv, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pubkey_1), RHN_OK); // This is dangerous ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_1, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_NESTED_TOKEN_SE_SIGNED_WITH_KEY_2, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This is safe ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_priv, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pubkey_1), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_1, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_advanced_parse(jwt, ADVANCED_NESTED_TOKEN_SE_SIGNED_WITH_KEY_2, R_PARSE_HEADER_JWK, R_FLAG_IGNORE_SERVER_CERTIFICATE), RHN_OK); // This isn't safe ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_priv, 0), RHN_OK); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 1); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwks_append_jwk(jwt->jwks_pubkey_sign, jwk_pubkey_1), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_1, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); #endif r_jwk_free(jwk_pub); r_jwk_free(jwk_priv); r_jwk_free(jwk_pubkey_1); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_quick_parse) { jwk_t * jwk_pub; jwt_t * jwt; struct _u_instance instance; char * http_key, * http_cert; ck_assert_ptr_ne(NULL, http_key = get_file_content(HTTPS_CERT_KEY)); ck_assert_ptr_ne(NULL, http_cert = get_file_content(HTTPS_CERT_PEM)); ck_assert_int_eq(ulfius_init_instance(&instance, 7468, NULL, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/x5u", NULL, 0, &callback_x5u_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_add_endpoint_by_val(&instance, "GET", "/jku", NULL, 0, &callback_jku_ecdsa_crt, NULL), U_OK); ck_assert_int_eq(ulfius_start_secure_framework(&instance, http_key, http_cert), U_OK); ck_assert_int_eq(r_jwk_init(&jwk_pub), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pub, jwk_pubkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne(NULL, jwt = r_jwt_quick_parse(TOKEN, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); r_jwt_free(jwt); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_INVALID_DOTS, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_INVALID_HEADER, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_INVALID_HEADER_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_INVALID_CLAIMS, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_INVALID_CLAIMS_B64, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_eq(NULL, jwt = r_jwt_quick_parse(TOKEN_UNSECURE, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_ptr_ne(NULL, jwt = r_jwt_quick_parse(TOKEN_UNSECURE, R_PARSE_UNSIGNED, R_FLAG_IGNORE_SERVER_CERTIFICATE)); r_jwt_free(jwt); ck_assert_ptr_ne(NULL, jwt = r_jwt_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_NONE, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 0); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); r_jwt_free(jwt); ck_assert_ptr_ne(NULL, jwt = r_jwt_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_ALL, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 4); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); r_jwt_free(jwt); ck_assert_ptr_ne(NULL, jwt = r_jwt_quick_parse(ADVANCED_TOKEN_SIGNED_WITH_ROOT_KEY, R_PARSE_HEADER_JWK|R_PARSE_HEADER_X5C, R_FLAG_IGNORE_SERVER_CERTIFICATE)); ck_assert_int_eq(r_jwks_size(jwt->jwks_pubkey_sign), 2); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pub, 0), RHN_OK); r_jwt_free(jwt); r_jwk_free(jwk_pub); o_free(http_key); o_free(http_cert); ulfius_stop_framework(&instance); ulfius_clean_instance(&instance); } END_TEST START_TEST(test_rhonabwy_jwk_in_header_invalid) { jwt_t * jwt, * jwt_parsed; jwk_t * jwk; json_t * j_jwk; char * str_jwt; time_t exp; time(&exp); exp+=JWT_CLAIM_EXP; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_init(&jwt_parsed), RHN_OK); ck_assert_int_eq(r_jwt_set_claims(jwt, R_JWT_CLAIM_ISS, JWT_CLAIM_ISS, R_JWT_CLAIM_SUB, JWT_CLAIM_SUB, R_JWT_CLAIM_AUD, JWT_CLAIM_AUD1, R_JWT_CLAIM_JTI, JWT_CLAIM_JTI, R_JWT_CLAIM_EXP, exp, R_JWT_CLAIM_NBF, R_JWT_CLAIM_NOW, R_JWT_CLAIM_IAT, R_JWT_CLAIM_NOW, R_JWT_CLAIM_STR, "scope", JWT_CLAIM_SCOPE, R_JWT_CLAIM_INT, "age", JWT_CLAIM_AGE, R_JWT_CLAIM_JSN, "verified", JWT_CLAIM_VERIFIED, R_JWT_CLAIM_TYP, JWT_CLAIM_TYP, R_JWT_CLAIM_CTY, JWT_CLAIM_CTY, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_privkey_ecdsa_str), RHN_OK); ck_assert_ptr_ne(NULL, j_jwk = json_loads(jwk_privkey_ecdsa_str, JSON_DECODE_ANY, NULL)); ck_assert_int_eq(r_jwt_set_header_json_t_value(jwt, "jwk", j_jwk), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_ES256), RHN_OK); ck_assert_ptr_ne(NULL, str_jwt = r_jwt_serialize_signed(jwt, jwk, 0)); ck_assert_int_eq(r_jwt_parse(jwt_parsed, str_jwt, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); r_jwt_free(jwt_parsed); r_jwk_free(jwk); json_decref(j_jwk); o_free(str_jwt); } END_TEST #endif START_TEST(test_rhonabwy_token_type) { ck_assert_int_eq(R_JWT_TYPE_NONE, r_jwt_token_type(NULL)); ck_assert_int_eq(R_JWT_TYPE_NONE, r_jwt_token_type("error")); ck_assert_int_eq(R_JWT_TYPE_NONE, r_jwt_token_type("error.error")); ck_assert_int_eq(R_JWT_TYPE_NONE, r_jwt_token_type(TOKEN_INVALID_DOTS)); ck_assert_int_eq(R_JWT_TYPE_NONE, r_jwt_token_type(TOKEN_ENC_INVALID_DOTS)); ck_assert_int_eq(R_JWT_TYPE_SIGN, r_jwt_token_type("error.error.but-no")); ck_assert_int_eq(R_JWT_TYPE_ENCRYPT, r_jwt_token_type("error.error.but-no.like-no.say-me")); ck_assert_int_eq(R_JWT_TYPE_SIGN, r_jwt_token_type(TOKEN)); ck_assert_int_eq(R_JWT_TYPE_SIGN, r_jwt_token_type(TOKEN_INVALID_HEADER)); ck_assert_int_eq(R_JWT_TYPE_SIGN, r_jwt_token_type(TOKEN_UNSECURE)); ck_assert_int_eq(R_JWT_TYPE_ENCRYPT, r_jwt_token_type(TOKEN_ENC)); ck_assert_int_eq(R_JWT_TYPE_ENCRYPT, r_jwt_token_type(TOKEN_ENC_INVALID_HEADER_B64)); ck_assert_int_eq(R_JWT_TYPE_ENCRYPT, r_jwt_token_type(TOKEN_ENC_INVALID_SIGNATURE)); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWT core function tests"); tc_core = tcase_create("test_rhonabwy_core"); tcase_add_test(tc_core, test_rhonabwy_init); tcase_add_test(tc_core, test_rhonabwy_sign_alg); tcase_add_test(tc_core, test_rhonabwy_enc_alg); tcase_add_test(tc_core, test_rhonabwy_set_header); tcase_add_test(tc_core, test_rhonabwy_get_header); tcase_add_test(tc_core, test_rhonabwy_set_full_header_error); tcase_add_test(tc_core, test_rhonabwy_set_full_header); tcase_add_test(tc_core, test_rhonabwy_get_full_header); tcase_add_test(tc_core, test_rhonabwy_set_claim); tcase_add_test(tc_core, test_rhonabwy_get_claim); tcase_add_test(tc_core, test_rhonabwy_set_full_claims); tcase_add_test(tc_core, test_rhonabwy_set_full_claims_str); tcase_add_test(tc_core, test_rhonabwy_get_full_claims); tcase_add_test(tc_core, test_rhonabwy_append_claims); tcase_add_test(tc_core, test_rhonabwy_set_sign_keys); tcase_add_test(tc_core, test_rhonabwy_set_sign_jwks); tcase_add_test(tc_core, test_rhonabwy_add_sign_keys_by_content); tcase_add_test(tc_core, test_rhonabwy_set_enc_keys); tcase_add_test(tc_core, test_rhonabwy_set_enc_jwks); tcase_add_test(tc_core, test_rhonabwy_add_enc_keys_by_content); tcase_add_test(tc_core, test_rhonabwy_set_claims); tcase_add_test(tc_core, test_rhonabwy_invalid_claims); tcase_add_test(tc_core, test_rhonabwy_validate_claims); tcase_add_test(tc_core, test_rhonabwy_validate_claims_aud_array); tcase_add_test(tc_core, test_rhonabwy_set_properties_error); tcase_add_test(tc_core, test_rhonabwy_set_properties); tcase_add_test(tc_core, test_rhonabwy_copy); tcase_add_test(tc_core, test_rhonabwy_set_enc_cypher_key_iv); tcase_add_test(tc_core, test_rhonabwy_token_type); #if GNUTLS_VERSION_NUMBER >= 0x030600 && defined(R_WITH_CURL) tcase_add_test(tc_core, test_rhonabwy_advanced_parse); tcase_add_test(tc_core, test_rhonabwy_quick_parse); tcase_add_test(tc_core, test_rhonabwy_jwk_in_header_invalid); #endif tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWT core tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwt_encrypt.c000066400000000000000000000545471452472117100171440ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define TOKEN "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_INVALID_HEADER_B64 ";error;.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_INVALID_CLAIMS_B64 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.;error;.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4eRWJ.94p-hjUgcWGiJsQ8TnnKtQ" #define TOKEN_INVALID_SIGNATURE "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.TGaK3fCgsGxLNuGbWR2j4Fi_hetyBLSRyadtdG0MAsXTnXlXsFb_wwFahZQASsLxwEEekZQ5EEkJb9gwu3uWaf3Oq58lOETa4Fb_Z1-WN1jvzF4DBEQLVl0azU62LbPsFHl8vWuuE7NF5oFX2V3CboQnFoWB1yyqWBJXkdEvFyIrHnNmQw9goPs2kjACnYdsNzMnP6SOYsYvguIJcvKnoBAbQYp0DA8OHXI6fW4P_zgZ7TQVCJLwpB0QoD_4Raaya3OABxQ7LJqhpYvk7iHGHnC-Ws23dmLCdv5WG_w6NEQwQLkuED8SXhUbirLeq4LRVxXdf8I1XTKesS6_NVJBNg.GMeHp_DOIg9h8sfGYE8fYg.XcRXOh492A8SPw8EEQ6mRe1kt7BNFqOgG8GqHR2g6CI4a_RI3JA2taxi3wc4wRWJ.94p-hjUgcWGiJsQ8TnnKtQ" const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RSA1_5\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RSA1_5\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":\"2\"}"; START_TEST(test_rhonabwy_encrypt_error) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_encrypted(jwt, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_ES256), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_encrypted(jwt, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_UNKNOWN), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_privkey_rsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_encrypted(jwt, NULL, 0), NULL); json_decref(j_value); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_encrypt_with_add_keys) { jwt_t * jwt; jwk_t * jwk_pubkey_rsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_encrypted(jwt, NULL, 0), NULL); r_jwk_free(jwk_pubkey_rsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_encrypt_with_key_in_serialize) { jwt_t * jwt; jwk_t * jwk_pubkey_rsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_encrypted(jwt, jwk_pubkey_rsa, 0), NULL); r_jwk_free(jwk_pubkey_rsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_encrypt_without_set_encrypt_alg) { jwt_t * jwt; jwk_t * jwk_pubkey_rsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_encrypted(jwt, NULL, 0), NULL); r_jwk_free(jwk_pubkey_rsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_error_key) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt(jwt, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_error_key_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_ENCRYPT); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_decrypt(jwt, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_error_token_invalid) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_CLAIMS_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_error_encryption_invalid) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt(jwt, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_encryption_ok) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt(jwt, jwk_privkey_rsa, 0), RHN_OK); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_decrypt_encryption_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_ENCRYPT); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwt_decrypt(jwt, jwk_privkey_rsa, 0), RHN_OK); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST /** * Valdate the encrypted JWT in Appendix A.1 of the JWT RFC * https://tools.ietf.org/html/rfc7519#appendix-A.1 */ START_TEST(test_rhonabwy_rfc_ok) { jwt_t * jwt; jwk_t * jwk_privkey; const char token[] = "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0." "QR1Owv2ug2WyPBnbQrRARTeEk9kDO2w8qDcjiHnSJflSdv1iNqhWXaKH4MqAkQtM" "oNfABIPJaZm0HaA415sv3aeuBWnD8J-Ui7Ah6cWafs3ZwwFKDFUUsWHSK-IPKxLG" "TkND09XyjORj_CHAgOPJ-Sd8ONQRnJvWn_hXV1BNMHzUjPyYwEsRhDhzjAD26ima" "sOTsgruobpYGoQcXUwFDn7moXPRfDE8-NoQX7N7ZYMmpUDkR-Cx9obNGwJQ3nM52" "YCitxoQVPzjbl7WBuB7AohdBoZOdZ24WlN1lVIeh8v1K4krB8xgKvRU8kgFrEn_a" "1rZgN5TiysnmzTROF869lQ." "AxY8DCtDaGlsbGljb3RoZQ." "MKOle7UQrG6nSxTLX6Mqwt0orbHvAKeWnDYvpIAeZ72deHxz3roJDXQyhxx0wKaM" "HDjUEOKIwrtkHthpqEanSBNYHZgmNOV7sln1Eu9g3J8." "fiK51VwhsxJ-siBMR-YFiA", privkey[] = "{\"kty\":\"RSA\","\ "\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl"\ "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre"\ "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_"\ "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI"\ "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU"\ "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\","\ "\"e\":\"AQAB\","\ "\"d\":\"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq"\ "1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry"\ "nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_"\ "0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj"\ "-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj"\ "T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ\","\ "\"p\":\"9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68"\ "ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP"\ "krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM\","\ "\"q\":\"uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y"\ "BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN"\ "-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0\","\ "\"dp\":\"w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv"\ "ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra"\ "Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs\","\ "\"dq\":\"o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff"\ "7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_"\ "odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU\","\ "\"qi\":\"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC"\ "tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ"\ "B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo\""\ "}"; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, privkey), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, token, 0), RHN_OK); ck_assert_int_eq(r_jwt_decrypt(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, "joe", R_JWT_CLAIM_EXP, 1300819370, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_ptr_eq(r_jwt_get_claim_json_t_value(jwt, "http://example.com/is_root"), json_true()); r_jwk_free(jwk_privkey); r_jwt_free(jwt); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWT encrypt function tests"); tc_core = tcase_create("test_rhonabwy_encrypt"); tcase_add_test(tc_core, test_rhonabwy_encrypt_error); tcase_add_test(tc_core, test_rhonabwy_encrypt_with_add_keys); tcase_add_test(tc_core, test_rhonabwy_encrypt_with_key_in_serialize); tcase_add_test(tc_core, test_rhonabwy_encrypt_without_set_encrypt_alg); tcase_add_test(tc_core, test_rhonabwy_decrypt_error_key); tcase_add_test(tc_core, test_rhonabwy_decrypt_error_key_with_add_keys); tcase_add_test(tc_core, test_rhonabwy_decrypt_error_token_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_error_encryption_invalid); tcase_add_test(tc_core, test_rhonabwy_decrypt_encryption_ok); tcase_add_test(tc_core, test_rhonabwy_decrypt_encryption_with_add_keys_ok); tcase_add_test(tc_core, test_rhonabwy_rfc_ok); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWT encrypt tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwt_nested.c000066400000000000000000002253421452472117100167330ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define TOKEN_SE "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.BMkD42WQBkpbOFtk6cAlK0vPS_zN3NJ1VVQFbgdnbVwbu21bJSQuHGypq"\ "vWXY336MC4uWoZ01E1Di4WD935Xv47UxIFmg_VLmCtvLPa9Bt7YncUHlM6IZ5EMUYJmasd3JKg5cs213djBUt4hsG0FBqYWZJGZovBBzHkjdI8qV7Vw29_xfBS_3LGiBYPnA"\ "MU8TFgKs49tAyWiDI6wb1rN59Hw5O-sQ1wVggVYuMwTmaYekiXCkDS8WMouYHQwq_183skoRuhG6NDHdw_NCMRFI6yfdaXDB3L_8O2ileWwGwlN1sDNPnFfUJGwb55D0Jc57"\ "vb4eWH0OSVo4Pk6wQlz-A.KDT-hqGQiYZgM5O2aMjbZg.88OzLv6i_VweilpNc_YNYR4p8m32dIUW_Hy3aYjyJA7Dfavwy5BsuNganQiN5Sq6CmNElRyoX2MLxbxrgkqKt1I"\ "6sYYavTPTcKTsdQW7vudwggmRJqGZn6kPl1OASlJ9Xnf0o5dRuBCKh0grHYl-b4L3pP56tvlx9tb9Cjb-wKpOjhl0sb8ItVLrc9Ez6BLOqGd4RH_tyBOK7na5Yrhcy4lvP8I"\ "1lmsjiQ8bTYzulnQhgtJHpgOim0p5NoSSjQDrBZYp-C0MIMsU2IQaFe7OC34g1j9j7IAvfBk8cXmBALZrci_3NBy2hTM55VYM0OcD6Fk4c6929NgwCGRh5WDthZtQtejkozI"\ "_iU3U-ufcGOA_JGj0QPuldK8SFJP9nRzCIRwbkCQmYvVEGzBjUB_AoNsTdwMdwH4-dslPWCypDVfDq8qIXIe2mswn0zQrhM39whWRuS0Wp-bN6R26fkQ9jQpbaTue_viV7gg"\ "4a3gPzW93-mqqwnM--2pbcKRFcSEYfYwxHCWoN_YFnsJow-t7V8hp68rlNurEIY3LxAYKYZUnqxaYlUe4mLxt6UO0thomw8deQyR5Jle-lS5vdE1oRA.HdJ_bLTq0p_hrUZj"\ "CUsomw" #define TOKEN_SE_INVALID_HEADER_B64 "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU.BMkD42WQBkpbOFtk6cAlK0vPS_zN3NJ1VVQFbgdnbV"\ "wbu21bJSQuHGypqvWXY336MC4uWoZ01E1Di4WD935Xv47UxIFmg_VLmCtvLPa9Bt7YncUHlM6IZ5EMUYJmasd3JKg5cs213djBUt4hsG0FBqYWZJGZovBBzHkjdI8qV7Vw29"\ "_xfBS_3LGiBYPnAMU8TFgKs49tAyWiDI6wb1rN59Hw5O-sQ1wVggVYuMwTmaYekiXCkDS8WMouYHQwq_183skoRuhG6NDHdw_NCMRFI6yfdaXDB3L_8O2ileWwGwlN1sDNPn"\ "FfUJGwb55D0Jc57vb4eWH0OSVo4Pk6wQlz-A.KDT-hqGQiYZgM5O2aMjbZg.88OzLv6i_VweilpNc_YNYR4p8m32dIUW_Hy3aYjyJA7Dfavwy5BsuNganQiN5Sq6CmNElRyo"\ "X2MLxbxrgkqKt1I6sYYavTPTcKTsdQW7vudwggmRJqGZn6kPl1OASlJ9Xnf0o5dRuBCKh0grHYl-b4L3pP56tvlx9tb9Cjb-wKpOjhl0sb8ItVLrc9Ez6BLOqGd4RH_tyBOK"\ "7na5Yrhcy4lvP8I1lmsjiQ8bTYzulnQhgtJHpgOim0p5NoSSjQDrBZYp-C0MIMsU2IQaFe7OC34g1j9j7IAvfBk8cXmBALZrci_3NBy2hTM55VYM0OcD6Fk4c6929NgwCGRh"\ "5WDthZtQtejkozI_iU3U-ufcGOA_JGj0QPuldK8SFJP9nRzCIRwbkCQmYvVEGzBjUB_AoNsTdwMdwH4-dslPWCypDVfDq8qIXIe2mswn0zQrhM39whWRuS0Wp-bN6R26fkQ9"\ "jQpbaTue_viV7gg4a3gPzW93-mqqwnM--2pbcKRFcSEYfYwxHCWoN_YFnsJow-t7V8hp68rlNurEIY3LxAYKYZUnqxaYlUe4mLxt6UO0thomw8deQyR5Jle-lS5vdE1oRA.H"\ "dJ_bLTq0p_hrUZjCUsomw" #define TOKEN_SE_INVALID_CLAIMS_B64 ";error;.BMkD42WQBkpbOFtk6cAlK0vPS_zN3NJ1VVQFbgdnbVwbu21bJSQuHGypqvWXY336MC4uWoZ01E1Di4WD935Xv47UxIFmg_VLmCtvLPa9Bt7YncUHlM"\ "6IZ5EMUYJmasd3JKg5cs213djBUt4hsG0FBqYWZJGZovBBzHkjdI8qV7Vw29_xfBS_3LGiBYPnAMU8TFgKs49tAyWiDI6wb1rN59Hw5O-sQ1wVggVYuMwTmaYekiXCkDS8WM"\ "ouYHQwq_183skoRuhG6NDHdw_NCMRFI6yfdaXDB3L_8O2ileWwGwlN1sDNPnFfUJGwb55D0Jc57vb4eWH0OSVo4Pk6wQlz-A.KDT-hqGQiYZgM5O2aMjbZg.88OzLv6i_Vwe"\ "ilpNc_YNYR4p8m32dIUW_Hy3aYjyJA7Dfavwy5BsuNganQiN5Sq6CmNElRyoX2MLxbxrgkqKt1I6sYYavTPTcKTsdQW7vudwggmRJqGZn6kPl1OASlJ9Xnf0o5dRuBCKh0gr"\ "HYl-b4L3pP56tvlx9tb9Cjb-wKpOjhl0sb8ItVLrc9Ez6BLOqGd4RH_tyBOK7na5Yrhcy4lvP8I1lmsjiQ8bTYzulnQhgtJHpgOim0p5NoSSjQDrBZYp-C0MIMsU2IQaFe7O"\ "C34g1j9j7IAvfBk8cXmBALZrci_3NBy2hTM55VYM0OcD6Fk4c6929NgwCGRh5WDthZtQtejkozI_iU3U-ufcGOA_JGj0QPuldK8SFJP9nRzCIRwbkCQmYvVEGzBjUB_AoNsT"\ "dwMdwH4-dslPWCypDVfDq8qIXIe2mswn0zQrhM39whWRuS0Wp-bN6R26fkQ9jQpbaTue_viV7gg4a3gPzW93-mqqwnM--2pbcKRFcSEYfYwxHCWoN_YFnsJow-t7V8hp68rl"\ "NurEIY3LxAYKYZUnqxaYlUe4mLxt6UO0thomw8deQyR5Jle-lS5vdE1oRA.HdJ_bLTq0p_hrUZjCUsomw" #define TOKEN_SE_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0BMkD42WQBkpbOFtk6cAlK0vPS_zN3NJ1VVQFbgdnbVwbu"\ "21bJSQuHGypqvWXY336MC4uWoZ01E1Di4WD935Xv47UxIFmg_VLmCtvLPa9Bt7YncUHlM6IZ5EMUYJmasd3JKg5cs213djBUt4hsG0FBqYWZJGZovBBzHkjdI8qV7Vw29_xf"\ "BS_3LGiBYPnAMU8TFgKs49tAyWiDI6wb1rN59Hw5O-sQ1wVggVYuMwTmaYekiXCkDS8WMouYHQwq_183skoRuhG6NDHdw_NCMRFI6yfdaXDB3L_8O2ileWwGwlN1sDNPnFfU"\ "JGwb55D0Jc57vb4eWH0OSVo4Pk6wQlz-A.KDT-hqGQiYZgM5O2aMjbZg.88OzLv6i_VweilpNc_YNYR4p8m32dIUW_Hy3aYjyJA7Dfavwy5BsuNganQiN5Sq6CmNElRyoX2M"\ "LxbxrgkqKt1I6sYYavTPTcKTsdQW7vudwggmRJqGZn6kPl1OASlJ9Xnf0o5dRuBCKh0grHYl-b4L3pP56tvlx9tb9Cjb-wKpOjhl0sb8ItVLrc9Ez6BLOqGd4RH_tyBOK7na"\ "5Yrhcy4lvP8I1lmsjiQ8bTYzulnQhgtJHpgOim0p5NoSSjQDrBZYp-C0MIMsU2IQaFe7OC34g1j9j7IAvfBk8cXmBALZrci_3NBy2hTM55VYM0OcD6Fk4c6929NgwCGRh5WD"\ "thZtQtejkozI_iU3U-ufcGOA_JGj0QPuldK8SFJP9nRzCIRwbkCQmYvVEGzBjUB_AoNsTdwMdwH4-dslPWCypDVfDq8qIXIe2mswn0zQrhM39whWRuS0Wp-bN6R26fkQ9jQp"\ "baTue_viV7gg4a3gPzW93-mqqwnM--2pbcKRFcSEYfYwxHCWoN_YFnsJow-t7V8hp68rlNurEIY3LxAYKYZUnqxaYlUe4mLxt6UO0thomw8deQyR5Jle-lS5vdE1oRA.HdJ_"\ "bLTq0p_hrUZjCUsomw" #define TOKEN_SE_INVALID_ENCRYPTION "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.BMkD42WQBkpbOFtk6cAlK0vPS_zN3NJ1VVQFbg"\ "dnbVwbu21bJSQuHGypqvWXY336MC4uWoZ01E1Di4WD935Xv47UxIFmg_VLmCtvLPa9Bt7YncUHlM6IZ5EMUYJmasd3JKg5cs213djBUt4hsG0FBqYWZJGZovBBzHkjdI8qV7"\ "Vw29_xfBS_3LGiBYPnAMU8TFgKs49tAyWiDI6wb1rN59Hw5O-sQ1wVggVYuMwTmaYekiXCkDS8WMouYHQwq_183skoRuhG6NDHdw_NCMRFI6yfdaXDB3L_8O2ileWwGwlN1s"\ "DNPnFfUJGwb55D0Jc57vb4eWH0OSVo4Pk6wQlz-A.KDT-hqGQiYZgM5O2aMjbZg.88OzLv6i_VweilpNc_YNYR4p8m32dIUW_Hy3aYjyJA7Dfavwy5BsuNganQiN5Sq6CmNE"\ "lRyoX2MLxbxrgkqKt1I6sYYavTPTcKTsdQW7vudwggmRJqGZn6kPl1OASlJ9Xnf0o5dRuBCKh0grHYl-b4L3pP56tvlx9tb9Cjb-wKpOjhl0sb8ItVLrc9Ez6BLOqGd4RH_t"\ "yBOK7na5Yrhcy4lvP8I1lmsjiQ8bTYzulnQhgtJHpgOim0p5NoSSjQDrBZYp-C0MIMsU2IQaFe7OC34g1j9j7IAvfBk8cXmBALZrci_3NBy2hTM55VYM0OcD6Fk4c6929Ngw"\ "CGRh5WDthZtQtejkozI_iU3U-ufcGOA_JGj0QPuldK8SFJP9nRzCIRwbkCQmYvVEGzBjUB_AoNsTdwMdwH4-dslPWCypDVfDq8qIXIe2mswn0zQrhM39whWRuS0Wp-bN6R26"\ "fkQ9jQpbaTue_viV7gg4a3gPzW93-mqqwnM--2pbcKRFcSEYfYwxHCWoN_YFnsJow-t7V8hp68rlNurEIY3LxAYKYZUnqxaYlUe4mLxt5UO0thomw8deQyR5Jle-lS5vdE1o"\ "RA.HdJ_bLTq0p_hrUZjCUsomw" #define TOKEN_ES "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1UwRXhYelVpTENKbGJtTWlPaUpCTVRJNFEwSk"\ "RMVWhUTWpVMkluMC5NQjFub3prM2xQOHRVVDVkZm5HdzBud1ktaXVBZ1FTMy1RYnpoWEs5WVBfVWtBYkVVTkhzVXBKME5GM2kwSkxtWHhnQ2VrWFlocWprSTBIUVNINmtmRj"\ "hqOXgteTJfX01nLU9tVnZVYjM4aTRneEZBVmhKTHd5TkNhV3NMLTk1VV95QW5DZDJ1eVpQOFdWOVRRY0xKOGxSaFZOTC1JcXFkMDctb2VDRVBfYmVxZzZwOWtod1c3Z291T0"\ "wzSG1IMkpBR3dOdXJHV3I2S3luQ2hXN1NBUHlvTVZWVEl1Mmwxc2pmM0E4b1pvZl9aZmd6ZmVGVFJseGVjb1dIVTQ3UmJRcTRUQ3pQdFlRZUxRVF9fTkk3VjI4T2RvaEw2am"\ "5lWkdKaTg2Umk2NnIwRXNoS0tJcWI4UTJwRzRUTS1QTm1BVWJsdzB4R2FRdGdGaDhFdGRKaGFMbmcudVA2ME0ya0ltQUZUTUdqYWhhMjlnQS5MZUNXQk9KMDhaVjVpaFJWRE"\ "93emgzYVRrTXFGYkIxMzBubXpfRUx3b1pQWEhLaWlmNHZRRGNIOGFkWWZCQ2dLLldLSEI4aGItNl81aDBmX1dEc05DZGc.gcUVTzWlR-R3T3w6cUyf8_C1gUTg6TWLO-QHps"\ "jirUJR3pRwz3w48SkPMladWFM6EU88cjCW_bo2xO-LTpgIhd78mjL0yUadVWodOjqEj19plr4A1pXV3TBmHoFr6FiqcifgL55K-PNRQsa001SlCYx8rLj033hEzbSTJiPEC2"\ "CJnwGZAfKGMK87LHXc_nxOvmaEIkbBY60nPcH1HNgbu6CSrk4M5GR6UWF_23QX8RbEQfKkADqjoiKOHdDE5-4mNej_vg-ycORXNuOCHw9iDHVZp_yEKgabayW-Xn0oPH0yam"\ "CC--RQyPohkT3R22T2Ma7BdgvVIu385Yh_JqTKFw" #define TOKEN_ES_INVALID_HEADER_B64 ";error;.ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1UwRXhYelVpTENKbGJtTWlPaUpCTVRJNFEwSkRMVWhUTWpVMkluMC5NQjFub3prM2xQOHRVVDVkZm"\ "5HdzBud1ktaXVBZ1FTMy1RYnpoWEs5WVBfVWtBYkVVTkhzVXBKME5GM2kwSkxtWHhnQ2VrWFlocWprSTBIUVNINmtmRjhqOXgteTJfX01nLU9tVnZVYjM4aTRneEZBVmhKTH"\ "d5TkNhV3NMLTk1VV95QW5DZDJ1eVpQOFdWOVRRY0xKOGxSaFZOTC1JcXFkMDctb2VDRVBfYmVxZzZwOWtod1c3Z291T0wzSG1IMkpBR3dOdXJHV3I2S3luQ2hXN1NBUHlvTV"\ "ZWVEl1Mmwxc2pmM0E4b1pvZl9aZmd6ZmVGVFJseGVjb1dIVTQ3UmJRcTRUQ3pQdFlRZUxRVF9fTkk3VjI4T2RvaEw2am5lWkdKaTg2Umk2NnIwRXNoS0tJcWI4UTJwRzRUTS"\ "1QTm1BVWJsdzB4R2FRdGdGaDhFdGRKaGFMbmcudVA2ME0ya0ltQUZUTUdqYWhhMjlnQS5MZUNXQk9KMDhaVjVpaFJWRE93emgzYVRrTXFGYkIxMzBubXpfRUx3b1pQWEhLaW"\ "lmNHZRRGNIOGFkWWZCQ2dLLldLSEI4aGItNl81aDBmX1dEc05DZGc.gcUVTzWlR-R3T3w6cUyf8_C1gUTg6TWLO-QHpsjirUJR3pRwz3w48SkPMladWFM6EU88cjCW_bo2xO"\ "-LTpgIhd78mjL0yUadVWodOjqEj19plr4A1pXV3TBmHoFr6FiqcifgL55K-PNRQsa001SlCYx8rLj033hEzbSTJiPEC2CJnwGZAfKGMK87LHXc_nxOvmaEIkbBY60nPcH1HN"\ "gbu6CSrk4M5GR6UWF_23QX8RbEQfKkADqjoiKOHdDE5-4mNej_vg-ycORXNuOCHw9iDHVZp_yEKgabayW-Xn0oPH0yamCC--RQyPohkT3R22T2Ma7BdgvVIu385Yh_JqTKFw" #define TOKEN_ES_INVALID_CLAIMS_B64 "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.;error;.gcUVTzWlR-R3T3w6cUyf8_C1gUTg6TWLO-QHpsjirUJR3pR"\ "wz3w48SkPMladWFM6EU88cjCW_bo2xO-LTpgIhd78mjL0yUadVWodOjqEj19plr4A1pXV3TBmHoFr6FiqcifgL55K-PNRQsa001SlCYx8rLj033hEzbSTJiPEC2CJnwGZAfK"\ "GMK87LHXc_nxOvmaEIkbBY60nPcH1HNgbu6CSrk4M5GR6UWF_23QX8RbEQfKkADqjoiKOHdDE5-4mNej_vg-ycORXNuOCHw9iDHVZp_yEKgabayW-Xn0oPH0yamCC--RQyPo"\ "hkT3R22T2Ma7BdgvVIu385Yh_JqTKFw" #define TOKEN_ES_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1UwRXhYelVpTENKbGJtTWlPaU"\ "pCTVRJNFEwSkRMVWhUTWpVMkluMC5NQjFub3prM2xQOHRVVDVkZm5HdzBud1ktaXVBZ1FTMy1RYnpoWEs5WVBfVWtBYkVVTkhzVXBKME5GM2kwSkxtWHhnQ2VrWFlocWprST"\ "BIUVNINmtmRjhqOXgteTJfX01nLU9tVnZVYjM4aTRneEZBVmhKTHd5TkNhV3NMLTk1VV95QW5DZDJ1eVpQOFdWOVRRY0xKOGxSaFZOTC1JcXFkMDctb2VDRVBfYmVxZzZwOW"\ "tod1c3Z291T0wzSG1IMkpBR3dOdXJHV3I2S3luQ2hXN1NBUHlvTVZWVEl1Mmwxc2pmM0E4b1pvZl9aZmd6ZmVGVFJseGVjb1dIVTQ3UmJRcTRUQ3pQdFlRZUxRVF9fTkk3Vj"\ "I4T2RvaEw2am5lWkdKaTg2Umk2NnIwRXNoS0tJcWI4UTJwRzRUTS1QTm1BVWJsdzB4R2FRdGdGaDhFdGRKaGFMbmcudVA2ME0ya0ltQUZUTUdqYWhhMjlnQS5MZUNXQk9KMD"\ "haVjVpaFJWRE93emgzYVRrTXFGYkIxMzBubXpfRUx3b1pQWEhLaWlmNHZRRGNIOGFkWWZCQ2dLLldLSEI4aGItNl81aDBmX1dEc05DZGc.gcUVTzWlR-R3T3w6cUyf8_C1gU"\ "Tg6TWLO-QHpsjirUJR3pRwz3w48SkPMladWFM6EU88cjCW_bo2xO-LTpgIhd78mjL0yUadVWodOjqEj19plr4A1pXV3TBmHoFr6FiqcifgL55K-PNRQsa001SlCYx8rLj033"\ "hEzbSTJiPEC2CJnwGZAfKGMK87LHXc_nxOvmaEIkbBY60nPcH1HNgbu6CSrk4M5GR6UWF_23QX8RbEQfKkADqjoiKOHdDE5-4mNej_vg-ycORXNuOCHw9iDHVZp_yEKgabay"\ "W-Xn0oPH0yamCC--RQyPohkT3R22T2Ma7BdgvVIu385Yh_JqTKFw" #define TOKEN_ES_INVALID_SIGNATURE "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1UwRXhYelVpTENKbGJt"\ "TWlPaUpCTVRJNFEwSkRMVWhUTWpVMkluMC5NQjFub3prM2xQOHRVVDVkZm5HdzBud1ktaXVBZ1FTMy1RYnpoWEs5WVBfVWtBYkVVTkhzVXBKME5GM2kwSkxtWHhnQ2VrWFlo"\ "cWprSTBIUVNINmtmRjhqOXgteTJfX01nLU9tVnZVYjM4aTRneEZBVmhKTHd5TkNhV3NMLTk1VV95QW5DZDJ1eVpQOFdWOVRRY0xKOGxSaFZOTC1JcXFkMDctb2VDRVBfYmVx"\ "ZzZwOWtod1c3Z291T0wzSG1IMkpBR3dOdXJHV3I2S3luQ2hXN1NBUHlvTVZWVEl1Mmwxc2pmM0E4b1pvZl9aZmd6ZmVGVFJseGVjb1dIVTQ3UmJRcTRUQ3pQdFlRZUxRVF9f"\ "Tkk3VjI4T2RvaEw2am5lWkdKaTg2Umk2NnIwRXNoS0tJcWI4UTJwRzRUTS1QTm1BVWJsdzB4R2FRdGdGaDhFdGRKaGFMbmcudVA2ME0ya0ltQUZUTUdqYWhhMjlnQS5MZUNX"\ "Qk9KMDhaVjVpaFJWRE93emgzYVRrTXFGYkIxMzBubXpfRUx3b1pQWEhLaWlmNHZRRGNIOGFkWWZCQ2dLLldLSEI4aGItNl81aDBmX1dEc05DZGc.gcUVTzWlR-R3T3w6cUyf"\ "8_C1gUTg6TWLO-QHpsjirUJR3pRwz3w48SkPMladWFM6EU88cjCW_bo2xO-LTpgIhd78mjL0yUadVWodOjqEj19plr4A1pXV3TBmHoFr6FiqcifgL55K-PNRQsa001SlCYx8"\ "rLj033hEzbSTJiPEC2CJnwGZAfKGMK87LHXc_nxO6maEIkbBY60nPcH1HNgbu6CSrk4M5GR6UWF_23QX8RbEQfKkADqjoiKOHdDE5-4mNej_vg-ycORXNuOCHw9iDHVZp_yE"\ "KgabayW-Xn0oPH0yamCC--RQyPohkT3R22T2Ma7BdgvVIu385Yh_JqTKFw" #define TOKEN_ES_UNSECURE "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIiwiY3R5IjoiSldUIn0K.ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1UwRXhYelVpTENKcmFXUWlPaUl5TURFeExUQTBMVEk"\ "1SWl3aVpXNWpJam9pUVRFeU9FTkNReTFJVXpJMU5pSjkuWS1DX0hwQm9xZ2dtNmxOUC14QUJFMEJqQ0VHRTVLTE9WYloyNkJHa0J2ZXJOZVMxZnJCbHBINThudjZlOE43cWF"\ "ubDcwSU1FNnYtLTlSang3ek9oU2ZNN0YtX0JYcVVWWkp1anA0bzBqeDZqY3MzMFA5eTFoLUY3SmhQdkpPazd6elJDV3lrNVFwTDUxa0g4bUF1WUFWZ0dGUGx1RmlacEhMQ3R"\ "qSExBNmF3ZFRsa01OZldLN3p1Q1h4NkhraVNyY0NEVUdRcHJuTlhxV0RLYnZudHdFalhuVlFLLTlWcEpha05GZ3ZwQjRqc2pVaDFkckVjbjZiakhXajE3MWJDaXFIQkctNlF"\ "iSi1CV2hOYnczdXB5VS1rTk9NejVoVkMzR0NScTFia1ZBZEQyMzZudFU3elhDSjh0WTNzY0ZTQnZHeGptR2RwckpwSHVGNXFLSXdOb2RBLnRSUVhYUjZGVXozWFF6d2ZDTWd"\ "lU1EudXN4ei1PQ2s4c0JuTXl4TjIzcWtCblktZllCbUZFWThjUlpfUktXZklPa2sxUzQzclNzVzNwNTNlbmpuVnJpdy5JSkVSYzY5alZJZjhfXzJZRjlfVEZ3." #define TOKEN_SE_UNSECURE "eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJraWQiOiIyMDExLTA0LTI5IiwiZW5jIjoiQTEyOENCQy1IUzI1NiJ9.u8HZdqJCoZfpOJ7-nU8Gls_"\ "KqrCUdFEKJxIaUJvYX1AHsV8r0fH4zdU426fhj2UlgRXay5vGrgNrP6N4OECIoOilv7T5vwUcPOgRPQDQAYjFR0nCywdZjfCG_0TvA7WXGplk9HexwPl-fu_YkxYzbqorv4p"\ "EEZK_OK7wbQXsKfv8MYJmn6hj3353Xp2q-FLtLFOU8jQLp-rp85Vsq_7Xa7BvsK3KkgTH83HEWNWAzqnCf0rAY5JMbxI6FpXXA-lw8Nb4WyDLoIzu-nT1LHWt7UADN7buONy"\ "c0URYjFLLE9tlQ-UV8o4iWHexJgYVCw44ilCjCVVf05gan3N_tga3Kg.-In3DtMLs-E-VaP3HOx46g.WJnkmlNb84S2Njpt2Fp0PkKHWfQM3mm9ZfixWeNtAW6wId9ziomO8"\ "H5app6Ga4AEwD4wRsn1oQn0UyQPTUu_iZdM7oPZsJFpUSsw0LG720OrSeDp5kZfwDVifsBsxBX0.eKUOmNL8ZmTakuzmLiGdfg" const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXj" "BZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qM" "QvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\",\"" "e\":\"AQAB\",\"alg\":\"RSA1_5\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX" "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6q" "MQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\"," "\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6Nq" "XSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xoj" "PLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q\",\"p" "\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVW" "lWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1" "dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk\",\"dp\":\"G4" "sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I" "24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6" "vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk\",\"qi\":\"GyM_p6Jr" "XySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmR" "fKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RSA1_5\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD8" "2B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW3b" "bsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9hNl5" "szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK4OPm" "N6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4GwyfF" "-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"kid\":\"2\"}"; const char jwk_privkey_rsa_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ANjyvB_f8xm80wMZM4Z7VO6UrTaFoDd68pgf2BCnnMsnH9lo4z40Yg-wWFhPhgZmSTFZjYUkWHGZoEpordO8xq6d_o3gkL2-ValGfxD" "82B7465IKNodJY7bldLaBqsVcQrottkL2UC3SXuIkDfZGG6_XU6Lr14rgNvw65mWavejYLNz2GVvmc54p36PArwPSY8fvdQsijrmrvsxx9av0qZASbxjfHkuibnsC4sW" "3bbsObZG_eOBkEwOwh_RVSV5GyprA4mZfnj_rTnWVN4OENa756cyk1JwWRzRWR0Q7xdlvcAzga3S3M_9dJb386Oip3SsFhIeZekyh2lAEi2E5VUWP8uOf-UCuEj04B9h" "Nl5szmNMts5AsBxBKwK_ixWNif8NBGQyA8mqRpYr7ddaBnCxreDuZyV6AwPBRfIOb29zgIi5OZzISsvFjFACDrgtX5sF_M_Q6usnyN-3LKoqHMqcL3dk0_a93gsuYMpK" "4OPmN6-82CekUsJ_m--3cZbknmeixPnRQGJLZNSZrpd0KZ1A0Dzmkr6RqWTlu51-cI50lyZXJiHR8hv-_tW2iRN3DWs6uI24S44-1-mSYfXL5vLYu6cBlIGYh55wLHK4" "GwyfF-GopckkedidJjX-zVPwJSq2CjmgitDvjoZMaDawoKgkH_uTWqobUNIS_4BPQiAET\",\"e\":\"AQAB\",\"d\":\"cf9SlRkzf5G1-4nRhlfmMBuVzPF4V87WD" "NOm0FGS1TkwxigUSIp0ALR0J6tZzKEQ0sqwz4ZipwbHsHHC7WDjsbu5l8mppNqP3ov5lu6VjejUt_9_2aTZrbBynLgUCPLK6VO90v_k7778Nq4lXARI5iQqgZCVyRa6L" "d2xVTBznBeDs3PprV2x4Sk1p7FHBaYW4mdURE6bWrsBXiJ_qiS8uMTG9fW_0JSAo0jH6obRNRqGvrAzDw3m4-ht-Bicndpq-dhi3tJdsE6wAp8u9X-SSehuTydJxN77-" "WdguV0DQJcK9Okz7bearhO_Ek8D_8XKPqH-mtYt6nid47APoT3kLNp1v5qiXQ8hLN4N1YM_s7LG44Gtns32Vzs7nwwBnBHAdhUxm5q40twVGXraw6SrTZC1hMpVCgJvp" "Ta-Ebz8RM7b7Qw142_4BRfi4p2QuOxoxY5ahmKD7xF8MH5307hPCC2-MO8FNe8c5sr4soEj93eFEf9V0UV5YHekopAKHDaS15sSbCIrDk78vFVmO2R6RCa3JKWLhg5Lk" "V5SeT5u3_TYdQ_3tgpZusuV534DbUV-Ztan2Emu4ds4-icL-SqkXzA_1TvDYtwnMxIWlG07gqTw-BshL2JuY18_8FjVzy4MWB7J8s2GVzJqKT8iY-L4JTJY5cvYsaQkF" "xRFEc2oE4E\",\"p\":\"AOLIjerOJBuW-Odoq2WSGSRzD5M5i4wwHV88wsNhzLsarB_ebyKwQwEKyalhOAUFTXjUQzg2G8FB9FLPmdgnUukWNCmd4c0pRBKCLNXHQwK" "uYTHf8lkfn2WchyGGIVQUFbgSdJtN6PGZbRa-26sz4xQgtyiFLerA8shwGl6Q07Sjd6CvRi-NvGqEW2LCz10iNPCqzQYfS0cPWhYXDrIqL_BFTo6A3bU0ifg_NukCvcR" "KZtlD2FaMCMF5xxfoCMtfXF1Owf_QwCAI5GebTbmLf3BmaCNjlmFm6nR1Vo-17Tk0nq3_rPYGiqLr2ANk8NHeMs6xe1GcWuO_nD1gE6o5QtM\",\"q\":\"APTlzxeo8" "IINCZulhQyOr3-zBTAtyaHgHQk2-AQYK98Ev6pfBvxwwMzAkSoVpCm1pxyp3JCSyjRSYFd4ibnZDjwd5p8RBfLr_zEnfx-IdUIrY7SyCGaFcKt2jS__4DUZQZu0-3Ysi" "dK8AECtVr0pa4XifZQnkqWnOeqkZqW1lT1yI8w4NbpCJVAT3ohhhRbTcCLFMhZjmWt5ZGgPz9r251PE-7i-04UvShSevhwdS6YJ3ma4gWhYbDMoADOXFfc5Qr1LxHd1w" "8LUk20bYTW_yZM8tDZxOQqkGivFW53kcgifzmKYjADNgQQojKO4KhG7xGxqvNrzNJQjM3SPdmUM4ME\",\"qi\":\"DwIv9lrwRP5ptwss0aNKgE1wRaaT8upXvzzlZA" "uNwolrVhmft_ELSNFuMRv-FCL1BK7YQgBwqux0_iRljvMcRogpeCs7w9DwLpivWyVcJf4PKZZWWlm7_kjIoVxRmNBzZUPpadCTQpAc8uGDtlz6OVgnvnb8FWtYDmHJMy" "UUdOb5Yxyg98P69pQ9ubPkkRwisDNnujjU3FCdiKZM1W1-l-qGJSHx0L8FEV3pckdOqzejw4jvb0mQroS5_UyeeY5nD93dwyI2faoD6K8xdh_Q1l6yW-7S3z7Z9qTkcP" "Ikb_BnWE59bAJniLDFx9KCSLMXv-_AhtY8AoGmSwT2rzAFpw\",\"dp\":\"ALDkPIZNOq7miMl_xElatw_OS_TLawTzNsXlkAl0jIvZFy9YghltoSX78yaSNW79HtvD" "vZbn5ahNuLSrR9XpfmtfLVrU0p8DtBw3u58YaTV7LUcI5nEMEHniqSjGBdMeQ36rrpbBI5Tn1sZqItAcjeBSUGtjzlgRHo6nmnnuv6Nj6ljEvpszFCeFi_6x86syllau" "83L2D_Kij-MxIv5nl7LzbH4NGGJSU9f1_u-rerfUTPrlR6biXaYERf5ouAtiG5qQZxQSEPor1XTXF75FiCb1Sf9om5DoBLLIH7fC8QGxAKC6EIBqw9Km4XxsTMd2aOz-" "VTFoIyEIgWcCPPSG648\",\"dq\":\"GW-xJdz3NhrSj6cOfbJoShQ3Cr0Gv1h-y5E5C3vTOrPMkI6UNC4l6F5r9XoP9gEXHWQLM7z7YZnYxd0QOQxxbQ8SAB2Nh6C5f" "cqDaqwKude14HPJaZSckkKbAYxLJli8NscCg1C28_tw70bRxo4BzAMtVfESS0BmRJfUzYtht-MeEr0X34O1Sm714yZ141wMvp_KxwaLTd1q72AND8orVskT-Clh4Oh7g" "k7Gojbsv48w2Wx6jHL6sgmKk9Eyh94br3uqKVpC_f6EXYXFgAaukitw8GKsMQ3AZiF2lZy_t2OZ1SXRDNhLeToY-XxMalEdYsFnYjp2kJhjZMzt2CsRQQ\",\"kid\":" "\"2\"}"; const char jwk_pubkey_sign_str[] = "{\"kty\":\"RSA\",\"n\":\"ANgV1GxZbGBMIqqX5QsNrQQnPLk8UpkqH_60EuaHsI8YnUkPmPVXJ_4z_ziqZizvvjp_RhhXX2DnHEQuYwI-SZaBlK1VJiiWH9EXrUeaz" "cpEryFUR0I5iBROcgRJfHSvRvC7D83-xg9xC-NGVvIQ2llduYzmaK8rfuiHWlGqow3O2m5os9NTortdQf7BeTniStDokFvZy-I4i24UFkemoNPWZ9MCN0WTea8n_TQmq9s" "VHGQtLIFqfblLxbSz_7m4g7_o3WfqlwXkVmCIu1wdzAjZV5BspBGrL0ed5Whpk9-bX69nUDvpcMAaPhuRwZ43e9koVRbVwXCNkne98VAs0_U\",\"e\":\"AQAB\",\"ki" "d\":\"3\"}"; const char jwk_privkey_sign_str[] = "{\"kty\":\"RSA\",\"n\":\"ANgV1GxZbGBMIqqX5QsNrQQnPLk8UpkqH_60EuaHsI8YnUkPmPVXJ_4z_ziqZizvvjp_RhhXX2DnHEQuYwI-SZaBlK1VJiiWH9EXrUea" "zcpEryFUR0I5iBROcgRJfHSvRvC7D83-xg9xC-NGVvIQ2llduYzmaK8rfuiHWlGqow3O2m5os9NTortdQf7BeTniStDokFvZy-I4i24UFkemoNPWZ9MCN0WTea8n_TQmq9" "sVHGQtLIFqfblLxbSz_7m4g7_o3WfqlwXkVmCIu1wdzAjZV5BspBGrL0ed5Whpk9-bX69nUDvpcMAaPhuRwZ43e9koVRbVwXCNkne98VAs0_U\",\"e\":\"AQAB\",\"d" "\":\"AKOVsyDreb5VJRFcuIrrqYWxZqkc37MQTvR1wrE_HAzYp4n-AuAJQT-Sga6WYY-3V53VaG1ZB93GWIHNVCsImJEWPEYUZjTnoeKbOBUzPoPYB3UF5oReJYSp9msEb" "vGvF9d65fYe4DYkcMl4IK5Uz9hDugrPC4VBOmwyu8-DjLkP8OH-N2-KhJvX_kLKgivfzD3KOp6wryLnKuZYn8N4E6rCiNSfKMgoM60bSHRNi0QHYB2jwqMU5T5EzdpD3Tu" "_ow6a-sXrW6SG1dtbuStck9hFcQ-QtRCeWoM5pFN8cKOsWBZd1unq-X3gMlCjdXUBUW7BYP44lpYsg1v9l_Ww64E\",\"p\":\"ANmlFUVM-836aC-wK-DekE3s3gl7GZ-" "9Qca8iKnaIeMszgyaLYkkbYNPpjjsiQHc37IG3axCaywK40PZqODzovL5PnUpwfNrnlMaI042rNaf8q1L4kvaBTkbO9Wbj0sTLMPt1frLQKBRsNDsYamRcL1SwvTC4aI7c" "gZBrNIBdPiR\",\"q\":\"AP4qYxRNGaI3aeZh5hgKPSGW82X8Ai2MzIKjzSDYmKGcD9HPRV0dAUmDCvqyjwCD6tL9iMtZKPz7VK66-KvV1n91WLMDtRzWs_eFFyDY7BYw" "47o6IQoZ2RxBT3-7WLhlFflaEner8k23zpGOjZbyzt0SIWRAYR0zlb7LrS_X4fcl\",\"qi\":\"fnlvhYXAn6V0X6gmlwooZUWo9bR7ObChNhrUzMVDOReUVOrzOhlzGh" "BW1TEFBBr8k44ZWBCTeVEQh--LFHwVvCgEjDBxfjUPUMkeyKZzLhpIUB_cFBAgI7Fyy0yuPpY0mS1PfMt5Y4b6g_JvdBWZZ8VhTcCVG7qDqoH_IJMXPNg\",\"dp\":\"E" "AsiQUSGf02JJpLG-UGOw5_FUk-XuPW7honZTSP-QX_JBJbM6oIb7IUPjLyq8M82Uio9ZvhSbCG1VQgTcdmj1mNXHk3gtS_msNuJZLeVEBEkU2_3k33TyrzeMUXRT0hvkVX" "T4zPeZLMA5LW4EUbeV6ZlJqPC_DGDm0B2G9jtpXE\",\"dq\":\"AMTictPUEcpOILO9HG985vPxKeTTfaBpVDbSymDqR_nQmZSOeg3yHQAkCco_rXTZu3rruR7El3K5Al" "VEMsNxp3IepbIuagrH6qsPpuXkA6YBAzdMNjHL6hnwIbQxnT1h2M7KzklzogRAIT0x706CEmq_06wEDvZ-8j3VKvhHxBwd\",\"kid\":\"3\"}"; const char jwk_pubkey_sign_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ALZfFvsvNegnsnjhAydGJ17C9Ny5-M1UqRbcgaPUFRqvfn2P2Yz5rjGTnfFKe9E6xANSNzKRdb5ltNeeJT0inSi2meACAXE68Ud7d2J" "vlkxQPvz1tJyCKvQFktGwlqwW5F8r_spfT1qJsf_DpZWjsXFrkY7sdrHJdoeQZDIYx0fsGdzlA0uGoGimPlCCExYLcqsjjh3Dqv8V1xJ4jm5S8198v3FJXXm5BN_GWAmEx" "uDOq6ul8MqcECXBQ4LavxFlB5kGgPsxvFjTK72_2YdNDQPkKmV56vShm50BaEqzXU0A2MYeTyabX7d4goI_B7IeX5tGqMjBrlX6hNS-VfqGMVM\",\"e\":\"AQAB\",\"" "kid\":\"4\"}"; const char jwk_privkey_sign_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ALZfFvsvNegnsnjhAydGJ17C9Ny5-M1UqRbcgaPUFRqvfn2P2Yz5rjGTnfFKe9E6xANSNzKRdb5ltNeeJT0inSi2meACAXE68Ud7d2" "JvlkxQPvz1tJyCKvQFktGwlqwW5F8r_spfT1qJsf_DpZWjsXFrkY7sdrHJdoeQZDIYx0fsGdzlA0uGoGimPlCCExYLcqsjjh3Dqv8V1xJ4jm5S8198v3FJXXm5BN_GWAmE" "xuDOq6ul8MqcECXBQ4LavxFlB5kGgPsxvFjTK72_2YdNDQPkKmV56vShm50BaEqzXU0A2MYeTyabX7d4goI_B7IeX5tGqMjBrlX6hNS-VfqGMVM\",\"e\":\"AQAB\"," "\"d\":\"HyIUlkT0-vDr8t7W3vmG9xJpItVMuCDfzNtP9lvaTnfvLBhGl154clY0_GAuywUxOS_r5GIYq6xJNxX0XX9vPOgPVMKC5IWfcwiM1O0fx19boWuArcc69fWNnu" "Z6kl5GFkk4cevbbCVdkcAgoG8Vd7tZWgDcMnWmGnZ35GV-f7Rw3kQTxge4V7T5-I5preMxRAV2YZ1zafIDpYXaOXWL9bX0vAApb5Vie1btPiOj7lZ_J0ChkkdIW-ZTiQZ0" "sTRo6c6qLVNHQLKAJ_I6QLMfiHAT8xFir3fgiUxNwxxifYOts_akh3-wJEs4r4G92hohmIiIKp2TABDc3WrmFDafYQ\",\"p\":\"ANVUDxAxNuR8Ds5W_3xpGgOKzypYG" "fimDrU_kRzXsdXOz4EkSYXG2SR7V854vvcgJDzFIihmaI_65LN_pk_6ZE1ddd8Qrud9nMtd5n9neEkOGTCsTO-TM4gLjyZQ3FCo_oCsJ6MiQRlOTw5pf1yH69q3QUd5e_5" "c75MYr4G0fPwn\",\"q\":\"ANrZ0K-ZdBt9uP1Bt0G7YmW3j41wFt1JnmOkX86YX6Q3wrI4YqiRfolVexAtQ1a1iRVY7ZGXhy_q0rDLPIpfYAy9LSS1NZHb_vu7C-p8hC" "ALxKa6bTGLeT4Z5LABHPBoMVCyKhlANMHhcUeNY76p4JwT1zwT7FIHamKgVKzv_CD1\",\"qi\":\"GUmL7fbgnNa2IQ13i3Xi3A5dXzgqBeVHb2HjAzCJhNCcg8jslpU4" "rmMoGAq_WagT-U3_NuUVnGWnHTPWHjFe9MkwxPpSIISbMRorOhsZMrlzg4vdyZ2Kt_zs3yNTb_KOYx6YxU3_93IdFU2XjlnUf4mDThVoTSRfNh-NMJgwLUw\",\"dp\":" "\"ALBi7IGK78RD_0oFDQIlNOkw4NI2PmMliou6n5WlktkiQtiY1GHUZL6Rbay-kcdrwAqvROr6ogJKhMcWCMGgW0bMvCVQeg3WAsr0PR2ixAZDrfhcvtBoefdG93nK6h-X" "W7ewoKV2MTVnVl6oRDKSACW72DHs9OUAmuaZRqSMQ7uJ\",\"dq\":\"AIgWpDddtB6YOl157Ov6CwD3eVPZXM50RgLuJwmAJREn_3D1sRvjhYz-08zGaLZVoo3cw7YiRN" "VeL2_yoY3mKwMg7B6EdHBkHhYJRSqmDT8kMj__c4E4mscsMNHlj0pLcEce0yDqlSPu_ZMh7-GTH3HOwKvCM9T6eYQk8SKtBNq1\",\"kid\":\"4\"}"; START_TEST(test_rhonabwy_serialize_se_error) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_privkey_ecdsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_UNKNOWN), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0), NULL); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_serialize_se_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_privkey_ecdsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, 0, NULL, 0)), NULL); o_free(token); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_serialize_se_with_key_in_serialize) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, jwk_privkey_ecdsa, 0, jwk_pubkey_rsa, 0)), NULL); o_free(token); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_serialize_es_error) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_privkey_ecdsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_UNKNOWN), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0), NULL); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_serialize_es_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_privkey_ecdsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, NULL, 0, NULL, 0)), NULL); o_free(token); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_serialize_es_with_key_in_serialize) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_ne((token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN, jwk_privkey_ecdsa, 0, jwk_pubkey_rsa, 0)), NULL); o_free(token); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_se_error_key) { jwt_t * jwt; jwk_t * jwk_privkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_se_error_key_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_se_error_token_invalid) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE_INVALID_CLAIMS_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_se_error_decryption_invalid) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE_INVALID_ENCRYPTION, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_verify_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_verify_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_se_verify_error) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); } END_TEST START_TEST(test_rhonabwy_nested_se_verify_with_add_keys_error) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_then_verify_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_se_decryption_then_verify_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_error_key) { jwt_t * jwt; jwk_t * jwk_privkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_es_error_key_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str_2), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_privkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_es_error_token_invalid) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES_INVALID_CLAIMS_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_es_error_signature_invalid) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_verify_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0, jwk_privkey_rsa, 0), RHN_OK); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_verify_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_OK); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_verify_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_OK); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); } END_TEST START_TEST(test_rhonabwy_nested_es_verify_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); } END_TEST START_TEST(test_rhonabwy_nested_es_verify_then_decryption_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_OK); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_verify_then_decryption_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_then_verify_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST START_TEST(test_rhonabwy_nested_es_decryption_then_verify_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()), * j_claims; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_ENCRYPT_THEN_SIGN); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, NULL, 0), RHN_OK); ck_assert_ptr_ne(j_claims = r_jwt_get_full_claims_json_t(jwt), NULL); ck_assert_int_eq(1, json_equal(j_claims, j_value)); r_jwt_free(jwt); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); json_decref(j_value); } END_TEST /** * Valdate the nested JWT in Appendix A.2 of the JWT RFC * https://tools.ietf.org/html/rfc7519#appendix-A.2 */ START_TEST(test_rhonabwy_rfc_ok) { jwt_t * jwt; jwk_t * jwk_privkey, * jwk_signkey; const char token[] = "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiSldU" "In0." "g_hEwksO1Ax8Qn7HoN-BVeBoa8FXe0kpyk_XdcSmxvcM5_P296JXXtoHISr_DD_M" "qewaQSH4dZOQHoUgKLeFly-9RI11TG-_Ge1bZFazBPwKC5lJ6OLANLMd0QSL4fYE" "b9ERe-epKYE3xb2jfY1AltHqBO-PM6j23Guj2yDKnFv6WO72tteVzm_2n17SBFvh" "DuR9a2nHTE67pe0XGBUS_TK7ecA-iVq5COeVdJR4U4VZGGlxRGPLRHvolVLEHx6D" "YyLpw30Ay9R6d68YCLi9FYTq3hIXPK_-dmPlOUlKvPr1GgJzRoeC9G5qCvdcHWsq" "JGTO_z3Wfo5zsqwkxruxwA." "UmVkbW9uZCBXQSA5ODA1Mg." "VwHERHPvCNcHHpTjkoigx3_ExK0Qc71RMEParpatm0X_qpg-w8kozSjfNIPPXiTB" "BLXR65CIPkFqz4l1Ae9w_uowKiwyi9acgVztAi-pSL8GQSXnaamh9kX1mdh3M_TT" "-FZGQFQsFhu0Z72gJKGdfGE-OE7hS1zuBD5oEUfk0Dmb0VzWEzpxxiSSBbBAzP10" "l56pPfAtrjEYw-7ygeMkwBl6Z_mLS6w6xUgKlvW6ULmkV-uLC4FUiyKECK4e3WZY" "Kw1bpgIqGYsw2v_grHjszJZ-_I5uM-9RA8ycX9KqPRp9gc6pXmoU_-27ATs9XCvr" "ZXUtK2902AUzqpeEUJYjWWxSNsS-r1TJ1I-FMJ4XyAiGrfmo9hQPcNBYxPz3GQb2" "8Y5CLSQfNgKSGt0A4isp1hBUXBHAndgtcslt7ZoQJaKe_nNJgNliWtWpJ_ebuOpE" "l8jdhehdccnRMIwAmU1n7SPkmhIl1HlSOpvcvDfhUN5wuqU955vOBvfkBOh5A11U" "zBuo2WlgZ6hYi9-e3w29bR0C2-pp3jbqxEDw3iWaf2dc5b-LnR0FEYXvI_tYk5rd" "_J9N0mg0tQ6RbpxNEMNoA9QWk5lgdPvbh9BaO195abQ." "AVO9iT5AV4CzvDJCdhSFlQ", privkey[] = "{\"kty\":\"RSA\"," "\"n\":\"sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1Wl" "UzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDpre" "cbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_" "7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBI" "Y2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU" "7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw\"," "\"e\":\"AQAB\"," "\"d\":\"VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq" "1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-ry" "nq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_" "0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj" "-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-Kyvj" "T1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ\"," "\"p\":\"9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68" "ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEP" "krdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM\"," "\"q\":\"uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-y" "BhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN" "-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0\"," "\"dp\":\"w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuv" "ngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcra" "Hawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs\"," "\"dq\":\"o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff" "7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_" "odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU\"," "\"qi\":\"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC" "tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ" "B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo\"" "}", signkey[] = "{\"kty\":\"RSA\"," "\"n\":\"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx" "HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs" "D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH" "SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV" "MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8" "NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ\"," "\"e\":\"AQAB\"," "\"d\":\"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I" "jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0" "BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn" "439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT" "CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh" "BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ\"," "\"p\":\"4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdi" "YrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPG" "BY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc\"," "\"q\":\"uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxa" "ewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA" "-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc\"," "\"dp\":\"BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3Q" "CLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb" "34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0\"," "\"dq\":\"h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa" "7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-ky" "NlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU\"," "\"qi\":\"IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2o" "y26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLU" "W0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U\"" "}"; ck_assert_int_eq(r_jwk_init(&jwk_privkey), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_signkey), RHN_OK); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey, privkey), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_signkey, signkey), RHN_OK); ck_assert_int_eq(r_jwt_add_enc_keys(jwt, jwk_privkey, NULL), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_signkey), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, token, 0), RHN_OK); ck_assert_int_eq(r_jwt_decrypt_verify_signature_nested(jwt, NULL, 0, NULL, 0), RHN_OK); ck_assert_int_eq(r_jwt_validate_claims(jwt, R_JWT_CLAIM_ISS, "joe", R_JWT_CLAIM_EXP, 1300819370, R_JWT_CLAIM_NOP), RHN_OK); ck_assert_ptr_eq(r_jwt_get_claim_json_t_value(jwt, "http://example.com/is_root"), json_true()); r_jwk_free(jwk_privkey); r_jwk_free(jwk_signkey); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_nested_unsecure) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa, * jwk_pubkey_rsa; jwk_t * jwk_pubkey_ecdsa, * jwk_privkey_rsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_NONE), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_set_enc_alg(jwt, R_JWA_ALG_RSA1_5), RHN_OK); ck_assert_int_eq(r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, jwk_privkey_ecdsa, 0, jwk_pubkey_rsa, 0), NULL); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwk_free(jwk_pubkey_rsa); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_ES_UNSECURE, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_SE_UNSECURE, 0), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT); ck_assert_int_eq(r_jwt_decrypt_nested(jwt, jwk_privkey_rsa, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature_nested(jwt, jwk_pubkey_ecdsa, 0), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwk_free(jwk_privkey_rsa); r_jwt_free(jwt); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_nested; s = suite_create("Rhonabwy JWT nested function tests"); tc_nested = tcase_create("test_rhonabwy_nested"); tcase_add_test(tc_nested, test_rhonabwy_serialize_se_error); tcase_add_test(tc_nested, test_rhonabwy_serialize_se_with_add_keys); tcase_add_test(tc_nested, test_rhonabwy_serialize_se_with_key_in_serialize); tcase_add_test(tc_nested, test_rhonabwy_serialize_es_error); tcase_add_test(tc_nested, test_rhonabwy_serialize_es_with_add_keys); tcase_add_test(tc_nested, test_rhonabwy_serialize_es_with_key_in_serialize); tcase_add_test(tc_nested, test_rhonabwy_nested_se_error_key); tcase_add_test(tc_nested, test_rhonabwy_nested_se_error_key_with_add_keys); tcase_add_test(tc_nested, test_rhonabwy_nested_se_error_token_invalid); tcase_add_test(tc_nested, test_rhonabwy_nested_se_error_decryption_invalid); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_verify_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_verify_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_se_verify_error); tcase_add_test(tc_nested, test_rhonabwy_nested_se_verify_with_add_keys_error); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_then_verify_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_se_decryption_then_verify_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_error_key); tcase_add_test(tc_nested, test_rhonabwy_nested_es_error_key_with_add_keys); tcase_add_test(tc_nested, test_rhonabwy_nested_es_error_token_invalid); tcase_add_test(tc_nested, test_rhonabwy_nested_es_error_signature_invalid); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_verify_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_verify_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_verify_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_verify_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_verify_then_decryption_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_verify_then_decryption_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_then_verify_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_es_decryption_then_verify_with_add_keys_ok); tcase_add_test(tc_nested, test_rhonabwy_rfc_ok); tcase_add_test(tc_nested, test_rhonabwy_nested_unsecure); tcase_set_timeout(tc_nested, 30); suite_add_tcase(s, tc_nested); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWT nested tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/jwt_sign.c000066400000000000000000000616501452472117100164110ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include #define TOKEN "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_HEADER "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ij.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_HEADER_B64 ";error;.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_CLAIMS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cn.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_CLAIMS_B64 "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.;error;.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_DOTS "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQeyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfpjqCsg" #define TOKEN_INVALID_SIGNATURE "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjMifQ.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9IEOR0hA-1f5AYmvsE5NUepLfp6qCsg" #define TOKEN_WITH_WHITESPACES " \v\n\teyJ0eXAiOiJKV1QiLCJhbGciOi\n\n\n \tJSUzI1NiIsImtpZCI6IjMifQ.eyJz\t\t \v\rdHIiOiJncnV0IiwiaW50I\n\t\vjo0Miwib2JqIjp0cnVlfQ.SgopnfP3vEE7HbuvfyYqZQZZsbu49GBR5w2YCesW7J0i_s5pVYPMIjl6xU4vOs-nV1lEwn7Z_OaQiyEhVftlOUkM5n7w57YViBZkus5C64S6LuQli150oXWNnis4La6qpg_12EocKffvmG940gL2dWg3dnQYenC-fgtX-CNcaIDZUL-NKq3iaQrwvdbuzNADlSBQUfHh80b7uyKgqcT4tboRyAnJXhcjZ-0NWxCIEusnbskmQEqdxEiq28xL8b_F2hDYe5ZuuHw8tmXcXNHUplswEefTCm0phbvi5D490nVBav6ri6zLTkC9\t\n \vIEOR0hA-1f5AYmvsE5NUepLfpjqCsg \t\n" #define TOKEN_UNSECURE "eyJhbGciOiJub25lIn0.eyJzdHIiOiJncnV0IiwiaW50Ijo0Miwib2JqIjp0cnVlfQ." const char jwk_pubkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRX"\ "jBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6"\ "qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw\""\ ",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_privkey_rsa_str[] = "{\"kty\":\"RSA\",\"n\":\"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKR"\ "XjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHz"\ "u6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKg"\ "w\",\"e\":\"AQAB\",\"d\":\"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2v"\ "v7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk"\ "5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoA"\ "C8Q\",\"p\":\"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7"\ "XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs\",\"q\":\"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3v"\ "obLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelx"\ "k\",\"dp\":\"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA7"\ "7Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0\",\"dq\":\"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA"\ "6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cg"\ "k\",\"qi\":\"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_m"\ "HZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU\",\"alg\":\"RS256\",\"kid\":\"2011-04-29\"}"; const char jwk_pubkey_sign_str[] = "{\"kty\":\"RSA\",\"n\":\"ANgV1GxZbGBMIqqX5QsNrQQnPLk8UpkqH_60EuaHsI8YnUkPmPVXJ_4z_ziqZizvvjp_RhhXX2DnHEQuYwI-SZaBlK1VJiiWH9"\ "EXrUeazcpEryFUR0I5iBROcgRJfHSvRvC7D83-xg9xC-NGVvIQ2llduYzmaK8rfuiHWlGqow3O2m5os9NTortdQf7BeTniStDokFvZy-I4i24UFkemoNPWZ9MC"\ "N0WTea8n_TQmq9sVHGQtLIFqfblLxbSz_7m4g7_o3WfqlwXkVmCIu1wdzAjZV5BspBGrL0ed5Whpk9-bX69nUDvpcMAaPhuRwZ43e9koVRbVwXCNkne98VAs0_"\ "U\",\"e\":\"AQAB\",\"kid\":\"3\"}"; const char jwk_privkey_sign_str[] = "{\"kty\":\"RSA\",\"n\":\"ANgV1GxZbGBMIqqX5QsNrQQnPLk8UpkqH_60EuaHsI8YnUkPmPVXJ_4z_ziqZizvvjp_RhhXX2DnHEQuYwI-SZaBlK1VJiiWH"\ "9EXrUeazcpEryFUR0I5iBROcgRJfHSvRvC7D83-xg9xC-NGVvIQ2llduYzmaK8rfuiHWlGqow3O2m5os9NTortdQf7BeTniStDokFvZy-I4i24UFkemoNPWZ9M"\ "CN0WTea8n_TQmq9sVHGQtLIFqfblLxbSz_7m4g7_o3WfqlwXkVmCIu1wdzAjZV5BspBGrL0ed5Whpk9-bX69nUDvpcMAaPhuRwZ43e9koVRbVwXCNkne98VAs0"\ "_U\",\"e\":\"AQAB\",\"d\":\"AKOVsyDreb5VJRFcuIrrqYWxZqkc37MQTvR1wrE_HAzYp4n-AuAJQT-Sga6WYY-3V53VaG1ZB93GWIHNVCsImJEWPEYUZj"\ "TnoeKbOBUzPoPYB3UF5oReJYSp9msEbvGvF9d65fYe4DYkcMl4IK5Uz9hDugrPC4VBOmwyu8-DjLkP8OH-N2-KhJvX_kLKgivfzD3KOp6wryLnKuZYn8N4E6rC"\ "iNSfKMgoM60bSHRNi0QHYB2jwqMU5T5EzdpD3Tu_ow6a-sXrW6SG1dtbuStck9hFcQ-QtRCeWoM5pFN8cKOsWBZd1unq-X3gMlCjdXUBUW7BYP44lpYsg1v9l_"\ "Ww64E\",\"p\":\"ANmlFUVM-836aC-wK-DekE3s3gl7GZ-9Qca8iKnaIeMszgyaLYkkbYNPpjjsiQHc37IG3axCaywK40PZqODzovL5PnUpwfNrnlMaI042rN"\ "af8q1L4kvaBTkbO9Wbj0sTLMPt1frLQKBRsNDsYamRcL1SwvTC4aI7cgZBrNIBdPiR\",\"q\":\"AP4qYxRNGaI3aeZh5hgKPSGW82X8Ai2MzIKjzSDYmKGcD"\ "9HPRV0dAUmDCvqyjwCD6tL9iMtZKPz7VK66-KvV1n91WLMDtRzWs_eFFyDY7BYw47o6IQoZ2RxBT3-7WLhlFflaEner8k23zpGOjZbyzt0SIWRAYR0zlb7LrS_"\ "X4fcl\",\"qi\":\"fnlvhYXAn6V0X6gmlwooZUWo9bR7ObChNhrUzMVDOReUVOrzOhlzGhBW1TEFBBr8k44ZWBCTeVEQh--LFHwVvCgEjDBxfjUPUMkeyKZzL"\ "hpIUB_cFBAgI7Fyy0yuPpY0mS1PfMt5Y4b6g_JvdBWZZ8VhTcCVG7qDqoH_IJMXPNg\",\"dp\":\"EAsiQUSGf02JJpLG-UGOw5_FUk-XuPW7honZTSP-QX_J"\ "BJbM6oIb7IUPjLyq8M82Uio9ZvhSbCG1VQgTcdmj1mNXHk3gtS_msNuJZLeVEBEkU2_3k33TyrzeMUXRT0hvkVXT4zPeZLMA5LW4EUbeV6ZlJqPC_DGDm0B2G9"\ "jtpXE\",\"dq\":\"AMTictPUEcpOILO9HG985vPxKeTTfaBpVDbSymDqR_nQmZSOeg3yHQAkCco_rXTZu3rruR7El3K5AlVEMsNxp3IepbIuagrH6qsPpuXkA"\ "6YBAzdMNjHL6hnwIbQxnT1h2M7KzklzogRAIT0x706CEmq_06wEDvZ-8j3VKvhHxBwd\",\"kid\":\"3\"}"; const char jwk_pubkey_sign_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ALZfFvsvNegnsnjhAydGJ17C9Ny5-M1UqRbcgaPUFRqvfn2P2Yz5rjGTnfFKe9E6xANSNzKRdb5ltNeeJT0inSi2meACAXE6"\ "8Ud7d2JvlkxQPvz1tJyCKvQFktGwlqwW5F8r_spfT1qJsf_DpZWjsXFrkY7sdrHJdoeQZDIYx0fsGdzlA0uGoGimPlCCExYLcqsjjh3Dqv8V1xJ4jm5S8198v3"\ "FJXXm5BN_GWAmExuDOq6ul8MqcECXBQ4LavxFlB5kGgPsxvFjTK72_2YdNDQPkKmV56vShm50BaEqzXU0A2MYeTyabX7d4goI_B7IeX5tGqMjBrlX6hNS-VfqG"\ "MVM\",\"e\":\"AQAB\",\"kid\":\"4\"}"; const char jwk_privkey_sign_str_2[] = "{\"kty\":\"RSA\",\"n\":\"ALZfFvsvNegnsnjhAydGJ17C9Ny5-M1UqRbcgaPUFRqvfn2P2Yz5rjGTnfFKe9E6xANSNzKRdb5ltNeeJT0inSi2meACAXE"\ "68Ud7d2JvlkxQPvz1tJyCKvQFktGwlqwW5F8r_spfT1qJsf_DpZWjsXFrkY7sdrHJdoeQZDIYx0fsGdzlA0uGoGimPlCCExYLcqsjjh3Dqv8V1xJ4jm5S8198v"\ "3FJXXm5BN_GWAmExuDOq6ul8MqcECXBQ4LavxFlB5kGgPsxvFjTK72_2YdNDQPkKmV56vShm50BaEqzXU0A2MYeTyabX7d4goI_B7IeX5tGqMjBrlX6hNS-Vfq"\ "GMVM\",\"e\":\"AQAB\",\"d\":\"HyIUlkT0-vDr8t7W3vmG9xJpItVMuCDfzNtP9lvaTnfvLBhGl154clY0_GAuywUxOS_r5GIYq6xJNxX0XX9vPOgPVMKC"\ "5IWfcwiM1O0fx19boWuArcc69fWNnuZ6kl5GFkk4cevbbCVdkcAgoG8Vd7tZWgDcMnWmGnZ35GV-f7Rw3kQTxge4V7T5-I5preMxRAV2YZ1zafIDpYXaOXWL9b"\ "X0vAApb5Vie1btPiOj7lZ_J0ChkkdIW-ZTiQZ0sTRo6c6qLVNHQLKAJ_I6QLMfiHAT8xFir3fgiUxNwxxifYOts_akh3-wJEs4r4G92hohmIiIKp2TABDc3Wrm"\ "FDafYQ\",\"p\":\"ANVUDxAxNuR8Ds5W_3xpGgOKzypYGfimDrU_kRzXsdXOz4EkSYXG2SR7V854vvcgJDzFIihmaI_65LN_pk_6ZE1ddd8Qrud9nMtd5n9ne"\ "EkOGTCsTO-TM4gLjyZQ3FCo_oCsJ6MiQRlOTw5pf1yH69q3QUd5e_5c75MYr4G0fPwn\",\"q\":\"ANrZ0K-ZdBt9uP1Bt0G7YmW3j41wFt1JnmOkX86YX6Q3"\ "wrI4YqiRfolVexAtQ1a1iRVY7ZGXhy_q0rDLPIpfYAy9LSS1NZHb_vu7C-p8hCALxKa6bTGLeT4Z5LABHPBoMVCyKhlANMHhcUeNY76p4JwT1zwT7FIHamKgVK"\ "zv_CD1\",\"qi\":\"GUmL7fbgnNa2IQ13i3Xi3A5dXzgqBeVHb2HjAzCJhNCcg8jslpU4rmMoGAq_WagT-U3_NuUVnGWnHTPWHjFe9MkwxPpSIISbMRorOhsZ"\ "Mrlzg4vdyZ2Kt_zs3yNTb_KOYx6YxU3_93IdFU2XjlnUf4mDThVoTSRfNh-NMJgwLUw\",\"dp\":\"ALBi7IGK78RD_0oFDQIlNOkw4NI2PmMliou6n5Wlktk"\ "iQtiY1GHUZL6Rbay-kcdrwAqvROr6ogJKhMcWCMGgW0bMvCVQeg3WAsr0PR2ixAZDrfhcvtBoefdG93nK6h-XW7ewoKV2MTVnVl6oRDKSACW72DHs9OUAmuaZR"\ "qSMQ7uJ\",\"dq\":\"AIgWpDddtB6YOl157Ov6CwD3eVPZXM50RgLuJwmAJREn_3D1sRvjhYz-08zGaLZVoo3cw7YiRNVeL2_yoY3mKwMg7B6EdHBkHhYJRSq"\ "mDT8kMj__c4E4mscsMNHlj0pLcEce0yDqlSPu_ZMh7-GTH3HOwKvCM9T6eYQk8SKtBNq1\",\"kid\":\"4\"}"; const unsigned char rsa_2048_pub[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwtpMAM4l1H995oqlqdMh\n" "uqNuffp4+4aUCwuFE9B5s9MJr63gyf8jW0oDr7Mb1Xb8y9iGkWfhouZqNJbMFry+\n" "iBs+z2TtJF06vbHQZzajDsdux3XVfXv9v6dDIImyU24MsGNkpNt0GISaaiqv51NM\n" "ZQX0miOXXWdkQvWTZFXhmsFCmJLE67oQFSar4hzfAaCulaMD+b3Mcsjlh0yvSq7g\n" "6swiIasEU3qNLKaJAZEzfywroVYr3BwM1IiVbQeKgIkyPS/85M4Y6Ss/T+OWi1Oe\n" "K49NdYBvFP+hNVEoeZzJz5K/nd6C35IX0t2bN5CVXchUFmaUMYk2iPdhXdsC720t\n" "BwIDAQAB\n" "-----END PUBLIC KEY-----\n"; START_TEST(test_rhonabwy_sign_error) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa; json_t * j_value = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_value), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_signed(jwt, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_signed(jwt, NULL, 0), NULL); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_UNKNOWN), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_privkey_ecdsa), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_signed(jwt, NULL, 0), NULL); json_decref(j_value); r_jwk_free(jwk_privkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_sign_with_add_keys) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_privkey_ecdsa, NULL), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_signed(jwt, NULL, 0), NULL); r_jwk_free(jwk_privkey_ecdsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_sign_with_key_in_serialize) { jwt_t * jwt; jwk_t * jwk_privkey_ecdsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_RS256), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_ecdsa, jwk_privkey_sign_str), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_signed(jwt, jwk_privkey_ecdsa, 0), NULL); r_jwk_free(jwk_privkey_ecdsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_sign_without_set_sign_alg) { jwt_t * jwt; jwk_t * jwk_privkey_rsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_privkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_privkey_rsa, jwk_privkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, jwk_privkey_rsa, NULL), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_signed(jwt, NULL, 0), NULL); r_jwk_free(jwk_privkey_rsa); json_decref(j_claims); o_free(token); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_error_key) { jwt_t * jwt; jwk_t * jwk_pubkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_SIGN); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pubkey_rsa, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pubkey_ecdsa, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_error_key_with_add_keys) { jwt_t * jwt; jwk_t * jwk_pubkey_rsa, * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_rsa, jwk_pubkey_rsa_str), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str_2), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_SIGN); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_rsa), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_pubkey_rsa); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_error_token_invalid) { jwt_t * jwt; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, NULL, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_HEADER_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_CLAIMS_B64, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_DOTS, 0), RHN_ERROR_PARAM); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_error_signature_invalid) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_INVALID_SIGNATURE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_SIGN); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_signature_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_SIGN); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pubkey_ecdsa, 0), RHN_OK); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_signature_with_whitespaces) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_WITH_WHITESPACES, 0), RHN_ERROR_PARAM); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_NONE); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pubkey_ecdsa, 0), RHN_ERROR_PARAM); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST START_TEST(test_rhonabwy_verify_signature_with_add_keys_ok) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk_pubkey_ecdsa, jwk_pubkey_sign_str), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_type(jwt), R_JWT_TYPE_SIGN); ck_assert_int_eq(r_jwt_add_sign_keys(jwt, NULL, jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_OK); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); } END_TEST /** * * This test validates that the vulnerability described in * https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/ * doesn't concern Rhonabwy * Basically, the attacker signs a JWT with the public key and the signature verification * doesn't check that the algorithm used is different from the expected one. * */ START_TEST(test_rhonabwy_verify_vulnerabilty_ok) { jwt_t * jwt_sign, * jwt_verify; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt_sign), RHN_OK); ck_assert_int_eq(r_jwt_init(&jwt_verify), RHN_OK); ck_assert_int_eq(r_jwt_add_sign_key_symmetric(jwt_sign, rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt_sign, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt_sign, R_JWA_ALG_HS256), RHN_OK); ck_assert_ptr_ne(token = r_jwt_serialize_signed(jwt_sign, NULL, 0), NULL); ck_assert_int_eq(r_jwt_add_sign_keys_pem_der(jwt_verify, R_FORMAT_PEM, NULL, 0, rsa_2048_pub, sizeof(rsa_2048_pub)), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt_verify, token, 0), RHN_OK); ck_assert_int_eq(r_jwt_verify_signature(jwt_verify, NULL, 0), RHN_ERROR_INVALID); o_free(token); json_decref(j_claims); r_jwt_free(jwt_sign); r_jwt_free(jwt_verify); } END_TEST START_TEST(test_rhonabwy_jwt_unsecure) { jwt_t * jwt; jwk_t * jwk_pubkey_ecdsa; json_t * j_claims = json_pack("{sssiso}", "str", "grut", "int", 42, "obj", json_true()); char * token; ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwk_init(&jwk_pubkey_ecdsa), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, TOKEN_UNSECURE, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_parse_unsecure(jwt, TOKEN_UNSECURE, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_NONE); ck_assert_int_eq(r_jwt_verify_signature(jwt, NULL, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_verify_signature(jwt, jwk_pubkey_ecdsa, 0), RHN_ERROR_INVALID); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_set_full_claims_json_t(jwt, j_claims), RHN_OK); ck_assert_int_eq(r_jwt_set_sign_alg(jwt, R_JWA_ALG_NONE), RHN_OK); ck_assert_ptr_eq(r_jwt_serialize_signed(jwt, NULL, 0), NULL); ck_assert_ptr_eq(r_jwt_serialize_signed(jwt, jwk_pubkey_ecdsa, 0), NULL); ck_assert_ptr_ne(token = r_jwt_serialize_signed_unsecure(jwt, jwk_pubkey_ecdsa, 0), NULL); o_free(token); ck_assert_ptr_ne(token = r_jwt_serialize_signed_unsecure(jwt, NULL, 0), NULL); r_jwt_free(jwt); ck_assert_int_eq(r_jwt_init(&jwt), RHN_OK); ck_assert_int_eq(r_jwt_parse(jwt, token, 0), RHN_ERROR_INVALID); ck_assert_int_eq(r_jwt_parse_unsecure(jwt, token, 0), RHN_OK); ck_assert_int_eq(r_jwt_get_sign_alg(jwt), R_JWA_ALG_NONE); o_free(token); r_jwk_free(jwk_pubkey_ecdsa); r_jwt_free(jwt); json_decref(j_claims); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy JWT sign function tests"); tc_core = tcase_create("test_rhonabwy_sign"); tcase_add_test(tc_core, test_rhonabwy_sign_error); tcase_add_test(tc_core, test_rhonabwy_sign_with_add_keys); tcase_add_test(tc_core, test_rhonabwy_sign_with_key_in_serialize); tcase_add_test(tc_core, test_rhonabwy_sign_without_set_sign_alg); tcase_add_test(tc_core, test_rhonabwy_verify_error_key); tcase_add_test(tc_core, test_rhonabwy_verify_error_key_with_add_keys); tcase_add_test(tc_core, test_rhonabwy_verify_error_token_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_error_signature_invalid); tcase_add_test(tc_core, test_rhonabwy_verify_signature_ok); tcase_add_test(tc_core, test_rhonabwy_verify_signature_with_whitespaces); tcase_add_test(tc_core, test_rhonabwy_verify_signature_with_add_keys_ok); tcase_add_test(tc_core, test_rhonabwy_verify_vulnerabilty_ok); tcase_add_test(tc_core, test_rhonabwy_jwt_unsecure); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy JWT sign tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/misc.c000066400000000000000000000627471452472117100155300ustar00rootroot00000000000000/* Public domain, no copyright. Use at your own risk. */ #include #include #include #include #include int _r_deflate_payload(const unsigned char * uncompressed, size_t uncompressed_len, unsigned char ** compressed, size_t * compressed_len); int _r_inflate_payload(const unsigned char * compressed, size_t compressed_len, unsigned char ** uncompressed, size_t * uncompressed_len); #define PAYLOAD "The true sign of intelligence is not knowledge but imagination." #define HUGE_PAYLOAD "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis efficitur lectus sit amet libero gravida eleifend. Nulla aliquam accumsan erat, quis tincidunt purus ultricies eu. Aenean eu dui ac diam placerat mollis. Duis eget tempor ipsum, vel ullamcorper purus. Ut eget quam vehicula, congue urna vel, dictum risus. Duis tristique est sed diam lobortis commodo. Proin et urna in odio malesuada sagittis. Donec lectus ligula, porttitor sed lorem ut, malesuada posuere neque. Nullam et nisl a felis congue mattis id non lectus.\ Quisque viverra hendrerit malesuada. Integer sollicitudin magna purus, in dignissim eros ullamcorper et. Praesent dignissim metus neque, eget tempor dolor tincidunt egestas. Nulla odio risus, tincidunt et egestas aliquet, pellentesque et eros. Etiam mattis orci a dui efficitur pharetra. Donec fermentum sem sed lacus finibus, nec luctus nisl vulputate. Donec sodales, nisi sed posuere maximus, lectus elit fermentum sapien, quis volutpat risus nisl vel dui. In vitae ante diam.\ Vivamus a nisl quam. Proin in lectus nunc. Aliquam condimentum tellus non feugiat aliquam. Nulla eu mi ligula. Proin auctor varius massa sed consectetur. Nulla et ligula pellentesque, egestas dui eu, gravida arcu. Maecenas vehicula feugiat tincidunt. Aenean sed sollicitudin ex. Cras luctus facilisis erat eu pharetra. Vestibulum interdum consequat tellus nec sagittis. Aliquam tincidunt eget lectus non bibendum. Mauris ut consectetur diam.\ Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed lorem lectus, ullamcorper consectetur quam ut, pharetra consectetur diam. Suspendisse eu erat quis nunc imperdiet lacinia vitae id arcu. Fusce non euismod urna. Aenean lacinia porta tellus nec rutrum. Aliquam est magna, aliquam non hendrerit eget, scelerisque quis sapien. Quisque consectetur et lacus non dapibus. Duis diam purus, vulputate convallis faucibus in, rutrum quis mi. Sed sed magna eget tellus semper suscipit a in augue.\ Aenean vitae tortor quam. Praesent pulvinar nulla a nisi egestas, laoreet tempus mauris ullamcorper. Nam vulputate molestie velit, quis laoreet felis suscipit euismod. Pellentesque a enim dapibus, tincidunt lorem vel, suscipit turpis. Phasellus id metus vehicula, luctus sem nec, maximus purus. Duis dictum elit quam, quis rhoncus ex ullamcorper ut. Donec fringilla augue vitae vestibulum maximus. Mauris vel arcu eget arcu bibendum ornare." #define TOKEN_SIGNED_INVALID_ZIP "eyJ6aXAiOiJERUYiLCJhbGciOiJIUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gRHVpcyBlZmZpY2l0dXIgbGVjdHVzIHNpdCBhbWV0IGxpYmVybyBncmF2aWRhIGVsZWlmZW5kLiBOdWxsYSBhbGlxdWFtIGFjY3Vtc2FuIGVyYXQsIHF1aXMgdGluY2lkdW50IHB1cnVzIHVsdHJpY2llcyBldS4gQWVuZWFuIGV1IGR1aSBhYyBkaWFtIHBsYWNlcmF0IG1vbGxpcy4gRHVpcyBlZ2V0IHRlbXBvciBpcHN1bSwgdmVsIHVsbGFtY29ycGVyIHB1cnVzLiBVdCBlZ2V0IHF1YW0gdmVoaWN1bGEsIGNvbmd1ZSB1cm5hIHZlbCwgZGljdHVtIHJpc3VzLiBEdWlzIHRyaXN0aXF1ZSBlc3Qgc2VkIGRpYW0gbG9ib3J0aXMgY29tbW9kby4gUHJvaW4gZXQgdXJuYSBpbiBvZGlvIG1hbGVzdWFkYSBzYWdpdHRpcy4gRG9uZWMgbGVjdHVzIGxpZ3VsYSwgcG9ydHRpdG9yIHNlZCBsb3JlbSB1dCwgbWFsZXN1YWRhIHBvc3VlcmUgbmVxdWUuIE51bGxhbSBldCBuaXNsIGEgZmVsaXMgY29uZ3VlIG1hdHRpcyBpZCBub24gbGVjdHVzLlF1aXNxdWUgdml2ZXJyYSBoZW5kcmVyaXQgbWFsZXN1YWRhLiBJbnRlZ2VyIHNvbGxpY2l0dWRpbiBtYWduYSBwdXJ1cywgaW4gZGlnbmlzc2ltIGVyb3MgdWxsYW1jb3JwZXIgZXQuIFByYWVzZW50IGRpZ25pc3NpbSBtZXR1cyBuZXF1ZSwgZWdldCB0ZW1wb3IgZG9sb3IgdGluY2lkdW50IGVnZXN0YXMuIE51bGxhIG9kaW8gcmlzdXMsIHRpbmNpZHVudCBldCBlZ2VzdGFzIGFsaXF1ZXQsIHBlbGxlbnRlc3F1ZSBldCBlcm9zLiBFdGlhbSBtYXR0aXMgb3JjaSBhIGR1aSBlZmZpY2l0dXIgcGhhcmV0cmEuIERvbmVjIGZlcm1lbnR1bSBzZW0gc2VkIGxhY3VzIGZpbmlidXMsIG5lYyBsdWN0dXMgbmlzbCB2dWxwdXRhdGUuIERvbmVjIHNvZGFsZXMsIG5pc2kgc2VkIHBvc3VlcmUgbWF4aW11cywgbGVjdHVzIGVsaXQgZmVybWVudHVtIHNhcGllbiwgcXVpcyB2b2x1dHBhdCByaXN1cyBuaXNsIHZlbCBkdWkuIEluIHZpdGFlIGFudGUgZGlhbS5WaXZhbXVzIGEgbmlzbCBxdWFtLiBQcm9pbiBpbiBsZWN0dXMgbnVuYy4gQWxpcXVhbSBjb25kaW1lbnR1bSB0ZWxsdXMgbm9uIGZldWdpYXQgYWxpcXVhbS4gTnVsbGEgZXUgbWkgbGlndWxhLiBQcm9pbiBhdWN0b3IgdmFyaXVzIG1hc3NhIHNlZCBjb25zZWN0ZXR1ci4gTnVsbGEgZXQgbGlndWxhIHBlbGxlbnRlc3F1ZSwgZWdlc3RhcyBkdWkgZXUsIGdyYXZpZGEgYXJjdS4gTWFlY2VuYXMgdmVoaWN1bGEgZmV1Z2lhdCB0aW5jaWR1bnQuIEFlbmVhbiBzZWQgc29sbGljaXR1ZGluIGV4LiBDcmFzIGx1Y3R1cyBmYWNpbGlzaXMgZXJhdCBldSBwaGFyZXRyYS4gVmVzdGlidWx1bSBpbnRlcmR1bSBjb25zZXF1YXQgdGVsbHVzIG5lYyBzYWdpdHRpcy4gQWxpcXVhbSB0aW5jaWR1bnQgZWdldCBsZWN0dXMgbm9uIGJpYmVuZHVtLiBNYXVyaXMgdXQgY29uc2VjdGV0dXIgZGlhbS5JbnRlcmR1bSBldCBtYWxlc3VhZGEgZmFtZXMgYWMgYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMuIFNlZCBsb3JlbSBsZWN0dXMsIHVsbGFtY29ycGVyIGNvbnNlY3RldHVyIHF1YW0gdXQsIHBoYXJldHJhIGNvbnNlY3RldHVyIGRpYW0uIFN1c3BlbmRpc3NlIGV1IGVyYXQgcXVpcyBudW5jIGltcGVyZGlldCBsYWNpbmlhIHZpdGFlIGlkIGFyY3UuIEZ1c2NlIG5vbiBldWlzbW9kIHVybmEuIEFlbmVhbiBsYWNpbmlhIHBvcnRhIHRlbGx1cyBuZWMgcnV0cnVtLiBBbGlxdWFtIGVzdCBtYWduYSwgYWxpcXVhbSBub24gaGVuZHJlcml0IGVnZXQsIHNjZWxlcmlzcXVlIHF1aXMgc2FwaWVuLiBRdWlzcXVlIGNvbnNlY3RldHVyIGV0IGxhY3VzIG5vbiBkYXBpYnVzLiBEdWlzIGRpYW0gcHVydXMsIHZ1bHB1dGF0ZSBjb252YWxsaXMgZmF1Y2lidXMgaW4sIHJ1dHJ1bSBxdWlzIG1pLiBTZWQgc2VkIG1hZ25hIGVnZXQgdGVsbHVzIHNlbXBlciBzdXNjaXBpdCBhIGluIGF1Z3VlLkFlbmVhbiB2aXRhZSB0b3J0b3IgcXVhbS4gUHJhZXNlbnQgcHVsdmluYXIgbnVsbGEgYSBuaXNpIGVnZXN0YXMsIGxhb3JlZXQgdGVtcHVzIG1hdXJpcyB1bGxhbWNvcnBlci4gTmFtIHZ1bHB1dGF0ZSBtb2xlc3RpZSB2ZWxpdCwgcXVpcyBsYW9yZWV0IGZlbGlzIHN1c2NpcGl0IGV1aXNtb2QuIFBlbGxlbnRlc3F1ZSBhIGVuaW0gZGFwaWJ1cywgdGluY2lkdW50IGxvcmVtIHZlbCwgc3VzY2lwaXQgdHVycGlzLiBQaGFzZWxsdXMgaWQgbWV0dXMgdmVoaWN1bGEsIGx1Y3R1cyBzZW0gbmVjLCBtYXhpbXVzIHB1cnVzLiBEdWlzIGRpY3R1bSBlbGl0IHF1YW0sIHF1aXMgcmhvbmN1cyBleCB1bGxhbWNvcnBlciB1dC4gRG9uZWMgZnJpbmdpbGxhIGF1Z3VlIHZpdGFlIHZlc3RpYnVsdW0gbWF4aW11cy4gTWF1cmlzIHZlbCBhcmN1IGVnZXQgYXJjdSBiaWJlbmR1bSBvcm5hcmUu.HoVfiZqrwC-QQF_etLZcMYEPEOY5_I8seUjgCb46qP4" #define TOKEN_ENCRYPTED_INVALID_ZIP "eyJ6aXAiOiJERUYiLCJhbGciOiJBMTI4S1ciLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.jcPWiKo22JIJpKB3bOl0bOCvF9aO5iZ8Ud8rU6RhCBludm1Zh5Nh6g.dGHvIuHMMc0dr8x0szYRVA.Va2TwbAhiSLVFGsfevD4lb5u2GiSROfysv4AO-uPOD9tE5O2IW3nFkMis5edghtVf3wvkMtjpAb73KWMDC1E-TEs5OVKJ8y4_lQaKgKsiyunuUb8J8h-R5XNXIi8G4yilnrM5tS5n8A-pFd34wL1vqPkdeCd8LVkfBl17DzLLO8sXvIRRdSr0H-t2H5UXyZykEckV5K3zwv7OuJ1iK3iAvwa_Pku0T-4RHvHU13QCjwULkTh3nyo9dpH35DDIjP_M77gG3HTa-u6wyMfNC-sXoPC7B4e_i5Um4itCIyXPXnEVJfuovcuUWDgh4QiaeIWuvA_Yh0XIlq93ZZuC7z3nonfOLftoeT6kq-82Sbd39wBtHxCCPN9XwOO6QCO-POXOuAWSKPr9HF0bYiCvE6W83imTeR0EI_oq7-pmGflo077jPW8H-gz4Vphp2jNwT0jIid_Um8q1eS0ApbbrA6MTgwKVDf7fchgyyLZp6rzREEfoBkf1c8bImwaiCO0otuwrrvghcPg5TiQCKvN3m1KWGlDdBV2076DE0nFGjEUH-1vfVrN7Y5T3i_ZyCZBNTxVHLXIiejcvaaghTqErLeXXUbxMGKEKe3nbEdSnrGeyDVKkEKKcsYVn2wDAU-WkMaFjoCbnJUjAbsm4hvscEFs-bTLebYNX6eCC-9ZzoZlOLUJ_5GvtQ7lWd59emQjrw0Xd2DhxfWyuKlPDPFue7nyTBqIxZ1rVlcGXQXuRKxy-y13ji2NG3O_5Ml6ntvgbEasp5x04mFON3f1z-SfYye86CHiQPQFVWhpuBUB4mAiGFarq3Al6rg1lwqhS-AR2HUVJvDuUgAxqtDPUmWRZZEjZKd-RYMPZ5lzle8mnZOUanRF4HBi6fMR11dPfldRXGzAOVwFyQhK3HKeWCVrZ2pLE3hzoURuiodA3ubx6zQ6MX2pdjIt1-Sl8jRDbCJi-VIqPuGwxvgHwTX2b0jxdtnnH93_mz3QgjxKYpNBFF4rDBKnWcrHFiwLbhx7sudaDByUV8cQyisRPuZEo2f2Z0epcU672xRl_eX3fZS03VEKIr78TOK7HQc_XnR3l18bnjP3JRAaMHLW7VXIS-0qL-d7IxNzbm_BYsECeDIKFNlyxrf9FJnJJlfUQWNKJKu3A4Q3uCg0wBCT2xi7klU9lnXNfFHiNe74dCvB14CIAzyoKR-BAyAjnEmnttSp7iNBTN9h-NCfvbPCh9JmAF4l92-wvfBeWvybpaSwBT4oVU0MWNyAzvRs66b0SdyDhJgDzjKhkCraBig6X5ZsvgPRmgLSZ49QSn828tLXn0fSfB78wrn0DIuB4rJyuei4UWADdXnu1i8XuOMNKKwIhgQDTNP1ELhhFimsuBFKqLRGlwH4luuq7ANjTrlmKWSF8kxoAWpsv0TBRRDHWpx-KW7YS-wM99sSEkWg4NfNE4w5KvVYy6mY4uNCcVYLLbZuqhWbRvoOtUwl_spwOyevK0DCN0iGZFti1tzwlMq01dNnjZTiCqOcJBCL1hxfQ9YIZSrFbCwxWwf-aa6ZpbLTj8uGaRFEpb6alXmJaitbQmzN-l7RxAKXb69abERyenxPE-jA2nvSO80RlH3DhDIutRsvG69-C_woDjjqGSzH03qpKTiwljGFkUqOelcyqi9_10yWIGR5KskbSKTczRrcnd8p9xlYqFoIB1duo-nvlBMpNUDLDosf_xBta7iJnFFBRm1b0HBSeXS538ZkIGAqw1LKRBI0jBn7LvQxMyxCSbofvSdFapfYPMOx7ITzUwOXY-9tJ2tTviMAcQUxcuvq8zdGEXydlToVg-6dBTMUo4ih-WKG48e4sNsCMZ6kC1J_I55jDRH7Tnbx0Fda3_tddm34VUTqmdzzrSQ9mq1_7evTrE15R4au0OJcsxJMZIAbm0Ki92n9AesUE__wfvCBam0AeB77wM8BX3YW6ukybCKBxpWL6jZFV7oP-dskXe1D7XSO1s-PAduhfqEGvgW_h06tQ8DxkIINc3vnNhwdBLFZWCszknQVS2fq-LFOHExsSx6zBSHR0O6jI_gDbyU40OzY21fLT-COp8qfmsHqa8SCjyjXsWXInqYUO8A9LExMSboWY1iByWVVeDeYglPM9GtkmBzQbLy_pKe5iEs71YfPOixXUtVvQqDmJRDAluxCW1ho0LXepvNPYppwvhTzg3iEbiGMlhzxEunyvEjjYOpbXAohnNL41LI4X_xKldim0Rzx0_jO84cqVbVzZUReSms4-l7ZJDWqA8WECRkgPgLMZAySWy0PEFLKRInpQ21RCq7NotsWeE8SY7R76cOreUCJVmsDWln5kEjBf8vGnacwv2oR5edF-BuVaIiryKvU2K-PJPGTX6dhIwVVWS1V3uDoelEQdA_SdLkye2uBDvn91fcvO7nG1MDLG_98GptECUGFk7soM2TgsQhlyqY92VaoQvKUwWM81PWkjMI7B-6ZquoxJJzyPdj6ZO1dyw-mkZheCpUlTU2mkmUC77rzlBCYQKwS66pcKSAeSP9TXaa-lbYrz1g0QaR1h3cpBvahxk71YGwqv-T8DPlsZw5T2X5l-W4Bg76FYVVp6JWjnpMQCYZMgQ5dQzDPDkPOarTotO0ZUEF0o1VchRMW6FgRIccgqnsa8sSPF2miIswfsoMkOQHuszsl94RBw61pu4t_N7PIo3ipZ7OHblm3PGJelEEAzO9F4qDiZG7Bpj0WLmEAh5h6aQdYh1kNtDlPH0pKmBWjyIjijV1amjWGSl9ZPqTGhh3upXpDnhgC65sGIcYkthwPrwvqhZqbppef6mG1jkhkisz0hVG3nV9FuLjcLtSTsL8harweziFhiPRkiaGDUebqKQVanyo-TrkZOosvx8FM6ugANIU2hYgS6NPGW_HoBznXei1nVLeDdy7_e3KRdPmksQAgt0FxTjg5OvxdsZkPDLE60NnDkAMQOJP8A13rBg36YgGiqAKs1MiuiEU5kP2nQFtSzZjzTWEFRDCAfM0Z-K_ZfYEAnSbbyZ_Y3VT59jHPLUhewv6lWZaJLgAxXk1vG_Je-q711sMamFGbeczW2LZQY3IzyYmTYJ_6hgI67TMjTBDvnB2m4R7VkTBHJAzPVKXPeFUhPFPCSe_J6mwwIU0fs9_JkyMMgtQ-T-MCGg1kZi5lAGBrCBxMSXoQclZLUdaHaGSq-GpoYt3vHlon-BXC.644LPTwW_DyY7p2TvrJUqg" const char jwk_key_symmetric[] = "{\"kty\":\"oct\",\"k\":\"AAECAwQFBgcICQoLDA0ODw\"}"; START_TEST(test_rhonabwy_info_json_t) { json_t * j_info_control = r_library_info_json_t(); json_t * j_info = json_pack("{sss{s[sssssss]}s{s[ssss]s[sssss]}}", "version", RHONABWY_VERSION_STR, "jws", "alg", "none", "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "jwe", "alg", "RSA1_5", "dir", "A128GCMKW", "A256GCMKW", "enc", "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A256GCM"); #if GNUTLS_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES512")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("EdDSA")); // json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256K")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS512")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060e json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192GCMKW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "enc"), json_string("A192GCM")); #endif #if NETTLE_VERSION_NUMBER >= 0x030400 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP-256")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A256KW")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS256+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS384+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS512+A256KW")); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A256KW")); #endif ck_assert_ptr_ne(j_info, NULL); ck_assert_ptr_ne(j_info_control, NULL); ck_assert_int_eq(json_equal(j_info, j_info_control), 1); json_decref(j_info); json_decref(j_info_control); } END_TEST START_TEST(test_rhonabwy_info_str) { char * j_info_control_str = r_library_info_json_str(); json_t * j_info = json_pack("{sss{s[sssssss]}s{s[ssss]s[sssss]}}", "version", RHONABWY_VERSION_STR, "jws", "alg", "none", "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "jwe", "alg", "RSA1_5", "dir", "A128GCMKW", "A256GCMKW", "enc", "A128CBC-HS256", "A192CBC-HS384", "A256CBC-HS512", "A128GCM", "A256GCM"); #if GNUTLS_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES512")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("EdDSA")); // json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("ES256K")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS256")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS384")); json_array_append_new(json_object_get(json_object_get(j_info, "jws"), "alg"), json_string("PS512")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060e json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192GCMKW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "enc"), json_string("A192GCM")); #endif #if NETTLE_VERSION_NUMBER >= 0x030400 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("RSA-OAEP-256")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("A256KW")); #endif #if GNUTLS_VERSION_NUMBER >= 0x03060d json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS256+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS384+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("PBES2-HS512+A256KW")); #endif #if NETTLE_VERSION_NUMBER >= 0x030600 json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A128KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A192KW")); json_array_append_new(json_object_get(json_object_get(j_info, "jwe"), "alg"), json_string("ECDH-ES+A256KW")); #endif json_t * j_info_control_parsed = json_loads(j_info_control_str, JSON_DECODE_ANY, NULL); ck_assert_ptr_ne(j_info, NULL); ck_assert_ptr_ne(j_info_control_str, NULL); ck_assert_ptr_ne(j_info_control_parsed, NULL); ck_assert_int_eq(json_equal(j_info, j_info_control_parsed), 1); json_decref(j_info); json_decref(j_info_control_parsed); r_free(j_info_control_str); } END_TEST START_TEST(test_rhonabwy_alg_conversion) { ck_assert_int_eq(r_str_to_jwa_alg("none"), R_JWA_ALG_NONE); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_NONE), "none"); ck_assert_int_eq(r_str_to_jwa_alg("HS256"), R_JWA_ALG_HS256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_HS256), "HS256"); ck_assert_int_eq(r_str_to_jwa_alg("HS384"), R_JWA_ALG_HS384); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_HS384), "HS384"); ck_assert_int_eq(r_str_to_jwa_alg("HS512"), R_JWA_ALG_HS512); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_HS512), "HS512"); ck_assert_int_eq(r_str_to_jwa_alg("ES256"), R_JWA_ALG_ES256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ES256), "ES256"); ck_assert_int_eq(r_str_to_jwa_alg("ES384"), R_JWA_ALG_ES384); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ES384), "ES384"); ck_assert_int_eq(r_str_to_jwa_alg("ES512"), R_JWA_ALG_ES512); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ES512), "ES512"); ck_assert_int_eq(r_str_to_jwa_alg("EdDSA"), R_JWA_ALG_EDDSA); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_EDDSA), "EdDSA"); ck_assert_int_eq(r_str_to_jwa_alg("ES256K"), R_JWA_ALG_ES256K); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ES256K), "ES256K"); ck_assert_int_eq(r_str_to_jwa_alg("RS256"), R_JWA_ALG_RS256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RS256), "RS256"); ck_assert_int_eq(r_str_to_jwa_alg("RS384"), R_JWA_ALG_RS384); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RS384), "RS384"); ck_assert_int_eq(r_str_to_jwa_alg("RS512"), R_JWA_ALG_RS512); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RS512), "RS512"); ck_assert_int_eq(r_str_to_jwa_alg("PS256"), R_JWA_ALG_PS256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PS256), "PS256"); ck_assert_int_eq(r_str_to_jwa_alg("PS384"), R_JWA_ALG_PS384); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PS384), "PS384"); ck_assert_int_eq(r_str_to_jwa_alg("PS512"), R_JWA_ALG_PS512); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PS512), "PS512"); ck_assert_int_eq(r_str_to_jwa_alg("EdDSA"), R_JWA_ALG_EDDSA); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_EDDSA), "EdDSA"); ck_assert_int_eq(r_str_to_jwa_alg("RSA1_5"), R_JWA_ALG_RSA1_5); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RSA1_5), "RSA1_5"); ck_assert_int_eq(r_str_to_jwa_alg("RSA-OAEP"), R_JWA_ALG_RSA_OAEP); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP), "RSA-OAEP"); ck_assert_int_eq(r_str_to_jwa_alg("RSA-OAEP-256"), R_JWA_ALG_RSA_OAEP_256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_RSA_OAEP_256), "RSA-OAEP-256"); ck_assert_int_eq(r_str_to_jwa_alg("A128KW"), R_JWA_ALG_A128KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A128KW), "A128KW"); ck_assert_int_eq(r_str_to_jwa_alg("A192KW"), R_JWA_ALG_A192KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A192KW), "A192KW"); ck_assert_int_eq(r_str_to_jwa_alg("A256KW"), R_JWA_ALG_A256KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A256KW), "A256KW"); ck_assert_int_eq(r_str_to_jwa_alg("dir"), R_JWA_ALG_DIR); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_DIR), "dir"); ck_assert_int_eq(r_str_to_jwa_alg("ECDH-ES"), R_JWA_ALG_ECDH_ES); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ECDH_ES), "ECDH-ES"); ck_assert_int_eq(r_str_to_jwa_alg("ECDH-ES+A128KW"), R_JWA_ALG_ECDH_ES_A128KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ECDH_ES_A128KW), "ECDH-ES+A128KW"); ck_assert_int_eq(r_str_to_jwa_alg("ECDH-ES+A192KW"), R_JWA_ALG_ECDH_ES_A192KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ECDH_ES_A192KW), "ECDH-ES+A192KW"); ck_assert_int_eq(r_str_to_jwa_alg("ECDH-ES+A256KW"), R_JWA_ALG_ECDH_ES_A256KW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_ECDH_ES_A256KW), "ECDH-ES+A256KW"); ck_assert_int_eq(r_str_to_jwa_alg("A128GCMKW"), R_JWA_ALG_A128GCMKW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A128GCMKW), "A128GCMKW"); ck_assert_int_eq(r_str_to_jwa_alg("A192GCMKW"), R_JWA_ALG_A192GCMKW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A192GCMKW), "A192GCMKW"); ck_assert_int_eq(r_str_to_jwa_alg("A256GCMKW"), R_JWA_ALG_A256GCMKW); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_A256GCMKW), "A256GCMKW"); ck_assert_int_eq(r_str_to_jwa_alg("PBES2-HS256+A128KW"), R_JWA_ALG_PBES2_H256); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PBES2_H256), "PBES2-HS256+A128KW"); ck_assert_int_eq(r_str_to_jwa_alg("PBES2-HS384+A192KW"), R_JWA_ALG_PBES2_H384); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PBES2_H384), "PBES2-HS384+A192KW"); ck_assert_int_eq(r_str_to_jwa_alg("PBES2-HS512+A256KW"), R_JWA_ALG_PBES2_H512); ck_assert_str_eq(r_jwa_alg_to_str(R_JWA_ALG_PBES2_H512), "PBES2-HS512+A256KW"); ck_assert_int_eq(r_str_to_jwa_alg("error"), R_JWA_ALG_UNKNOWN); ck_assert_ptr_eq(r_jwa_alg_to_str(R_JWA_ALG_UNKNOWN), NULL); } END_TEST START_TEST(test_rhonabwy_enc_conversion) { ck_assert_int_eq(r_str_to_jwa_enc("A128CBC-HS256"), R_JWA_ENC_A128CBC); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A128CBC), "A128CBC-HS256"); ck_assert_int_eq(r_str_to_jwa_enc("A192CBC-HS384"), R_JWA_ENC_A192CBC); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A192CBC), "A192CBC-HS384"); ck_assert_int_eq(r_str_to_jwa_enc("A256CBC-HS512"), R_JWA_ENC_A256CBC); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A256CBC), "A256CBC-HS512"); ck_assert_int_eq(r_str_to_jwa_enc("A128GCM"), R_JWA_ENC_A128GCM); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A128GCM), "A128GCM"); ck_assert_int_eq(r_str_to_jwa_enc("A192GCM"), R_JWA_ENC_A192GCM); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A192GCM), "A192GCM"); ck_assert_int_eq(r_str_to_jwa_enc("A256GCM"), R_JWA_ENC_A256GCM); ck_assert_str_eq(r_jwa_enc_to_str(R_JWA_ENC_A256GCM), "A256GCM"); ck_assert_int_eq(r_str_to_jwa_enc("error"), R_JWA_ENC_UNKNOWN); ck_assert_ptr_eq(r_jwa_enc_to_str(R_JWA_ENC_UNKNOWN), NULL); } END_TEST START_TEST(test_rhonabwy_inflate) { unsigned char in_1[] = PAYLOAD, in_2[] = HUGE_PAYLOAD, * out_1 = NULL, * out_2 = NULL; size_t out_1_len = 0, out_2_len = 0; ck_assert_int_eq(_r_deflate_payload(in_1, sizeof(in_1), &out_1, &out_1_len), RHN_OK); ck_assert_int_eq(_r_inflate_payload(out_1, out_1_len, &out_2, &out_2_len), RHN_OK); ck_assert_int_eq(sizeof(in_1), out_2_len); ck_assert_int_eq(0, memcmp(in_1, out_2, out_2_len)); r_free(out_1); r_free(out_2); ck_assert_int_eq(_r_deflate_payload(in_2, sizeof(in_2), &out_1, &out_1_len), RHN_OK); ck_assert_int_eq(_r_inflate_payload(out_1, out_1_len, &out_2, &out_2_len), RHN_OK); ck_assert_int_eq(sizeof(in_2), out_2_len); ck_assert_int_eq(0, memcmp(in_2, out_2, out_2_len)); r_free(out_1); r_free(out_2); ck_assert_int_ne(_r_inflate_payload(in_1, sizeof(in_1), &out_1, &out_1_len), RHN_OK); r_free(out_1); ck_assert_int_ne(_r_inflate_payload(in_2, sizeof(in_2), &out_1, &out_1_len), RHN_OK); r_free(out_1); } END_TEST START_TEST(test_rhonabwy_invalid_deflate_payload) { jws_t * jws; jwe_t * jwe; jwk_t * jwk; ck_assert_int_eq(r_jwk_init(&jwk), RHN_OK); ck_assert_int_eq(r_jwk_import_from_json_str(jwk, jwk_key_symmetric), RHN_OK); ck_assert_int_eq(r_jws_init(&jws), RHN_OK); ck_assert_int_ne(r_jws_parse(jws, TOKEN_SIGNED_INVALID_ZIP, 0), RHN_OK); ck_assert_int_eq(r_jwe_init(&jwe), RHN_OK); ck_assert_int_eq(r_jwe_parse(jwe, TOKEN_ENCRYPTED_INVALID_ZIP, 0), RHN_OK); ck_assert_int_ne(r_jwe_decrypt(jwe, jwk, 0), RHN_OK); r_jwk_free(jwk); r_jws_free(jws); r_jwe_free(jwe); } END_TEST static Suite *rhonabwy_suite(void) { Suite *s; TCase *tc_core; s = suite_create("Rhonabwy misc tests"); tc_core = tcase_create("test_rhonabwy_misc"); tcase_add_test(tc_core, test_rhonabwy_info_json_t); tcase_add_test(tc_core, test_rhonabwy_info_str); tcase_add_test(tc_core, test_rhonabwy_alg_conversion); tcase_add_test(tc_core, test_rhonabwy_enc_conversion); tcase_add_test(tc_core, test_rhonabwy_inflate); tcase_add_test(tc_core, test_rhonabwy_invalid_deflate_payload); tcase_set_timeout(tc_core, 30); suite_add_tcase(s, tc_core); return s; } int main(int argc, char *argv[]) { int number_failed; Suite *s; SRunner *sr; //y_init_logs("Rhonabwy", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting Rhonabwy misc tests"); r_global_init(); s = rhonabwy_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); srunner_free(sr); r_global_close(); //y_close_logs(); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } rhonabwy-1.1.13/test/run_test.sh000077500000000000000000000005751452472117100166220ustar00rootroot00000000000000#!/bin/bash printf_new() { str=$1 num=$2 v=$(printf "%-${num}s" "$str") printf "${v// / }" } RED='\033[0;31m' GREEN='\033[0;32m' NC='\033[0m' # No Color COMMAND=$1 CHRLEN=${#COMMAND} NBSP=$((32-$CHRLEN)) printf "Run $1" printf_new " " $NBSP $1 $2 $3 $4 $5 $6 $7 $8 $9 1>$1.log 2>&1 if [ $? -ne 0 ] then printf "${RED}FAIL${NC}\n" else printf "${GREEN}SUCCESS${NC}\n" fi rhonabwy-1.1.13/tools/000077500000000000000000000000001452472117100145725ustar00rootroot00000000000000rhonabwy-1.1.13/tools/rnbyc/000077500000000000000000000000001452472117100157075ustar00rootroot00000000000000rhonabwy-1.1.13/tools/rnbyc/Makefile000066400000000000000000000173411452472117100173550ustar00rootroot00000000000000# # rnbyc: Rhonabwy command-line tool # # Makefile used to build the software # # Copyright 2020-2022 Nicolas Mora # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU GENERAL PUBLIC LICENSE # License as published by the Free Software Foundation; # version 3 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU GENERAL PUBLIC LICENSE for more details. # # You should have received a copy of the GNU General Public # License along with this program. If not, see . # CC=gcc RHONABWY_INCLUDE=../../include RHONABWY_LOCATION=../../src DESTDIR=/usr/local CFLAGS+=-Wall -Werror -Wextra -Wconversion -I$(RHONABWY_INCLUDE) $(ADDITIONALFLAGS) $(CPPFLAGS) LIBS=-lc -lrhonabwy -lorcania -lyder -ljansson -lgnutls -L$(RHONABWY_LOCATION) RHONABWY_LIBRARY=../../src/librhonabwy.so VALGRIND_COMMAND=valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all --track-origins=yes CLAIMS='{"plop":"grut"}' PASSWORD='RainbowDash' DPOP="eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwiaWF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg" all: rnbyc all: ADDITIONALFLAGS= -O3 clean: rm -f *.o rnbyc valgrind-*.txt priv.jwks pub.jwks symkey.jwks token?.jwt debug: ADDITIONALFLAGS=-DDEBUG -g -O0 debug: rnbyc $(RHONABWY_LIBRARY): cd $(RHONABWY_LOCATION) && $(MAKE) debug rnbyc: $(RHONABWY_LIBRARY) rnbyc.c $(CC) -o rnbyc $(CFLAGS) rnbyc.c $(LIBS) install: rnbyc mkdir -p $(DESTDIR)/bin $(DESTDIR)/man/man1/ install -m755 rnbyc $(DESTDIR)/bin install -m644 rnbyc.1 $(DESTDIR)/man/man1/ uninstall: rm -f $(DESTDIR)/bin/rnbyc manpage: rnbyc help2man ./rnbyc -s 1 -n "JWK and JWT parser and generator" > rnbyc.1 test: test-jwks test-serialize test-parse test-jwks: debug # JWKS $(VALGRIND_COMMAND) ./rnbyc -h 2>valgrind-01.txt $(VALGRIND_COMMAND) ./rnbyc -v 2>valgrind-02.txt $(VALGRIND_COMMAND) ./rnbyc --error 2>valgrind-03.txt || true $(VALGRIND_COMMAND) ./rnbyc -j -g RSA2048 -o priv.jwks -p pub.jwks 2>valgrind-04.txt $(VALGRIND_COMMAND) ./rnbyc -j -f priv.jwks -f pub.jwks 2>valgrind-05.txt $(VALGRIND_COMMAND) ./rnbyc -j -g oct256 -k "oct-1" -o symkey.jwks 2>valgrind-06.txt $(VALGRIND_COMMAND) ./rnbyc -j -g EC256 -n 4 2>valgrind-07.txt $(VALGRIND_COMMAND) ./rnbyc -j -g EC384 -a "plop" -e "grut" 2>valgrind-08.txt || true $(VALGRIND_COMMAND) ./rnbyc -j -g Ed25519 2>valgrind-09.txt $(VALGRIND_COMMAND) ./rnbyc -j -g error 2>valgrind-10.txt || true cat priv.jwks | $(VALGRIND_COMMAND) ./rnbyc -j -i 2>valgrind-11.txt test-serialize: debug # Serialize JWT $(VALGRIND_COMMAND) ./rnbyc -s 'error' 2>valgrind-20.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) 2>valgrind-21.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K symkey.jwks -a HS256 1>token0.jwt 2>valgrind-22.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P pub.jwks 2>valgrind-23.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P pub.jwks -l RSA1_5 1>token1.jwt 2>valgrind-24.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P priv.jwks -l RSA1_5 2>valgrind-25.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P pub.jwks -l RSA-OAEP 1>token4.jwt 2>valgrind-26.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P priv.jwks -l RSA-OAEP 2>valgrind-27.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P pub.jwks -l RSA-OAEP-256 1>token5.jwt 2>valgrind-28.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P priv.jwks -l RSA-OAEP-256 2>valgrind-29.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K priv.jwks 2>valgrind-30.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K priv.jwks -a RS256 1>token2.jwt 2>valgrind-31.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K pub.jwks -a RS256 2>valgrind-32.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K priv.jwks -P pub.jwks -a RS256 -l RSA1_5 1>token3.jwt 2>valgrind-33.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K priv.jwks -P pub.jwks -a RS256 -l RSA-OAEP 1>token6.jwt 2>valgrind-34.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K priv.jwks -P pub.jwks -a RS256 -l RSA-OAEP-256 1>token7.jwt 2>valgrind-35.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -K token0.jwt 2>valgrind-36.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -P token0.jwt 2>valgrind-37.txt || true $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -W $(PASSWORD) -l PBES2-HS256+A128KW 1>token8.jwt 2>valgrind-38.txt $(VALGRIND_COMMAND) ./rnbyc -s $(CLAIMS) -W $(PASSWORD) -l RSA-OAEP 2>valgrind-39.txt || true test-parse: debug # Parse JWT $(VALGRIND_COMMAND) ./rnbyc -t "error" 2>valgrind-40.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token0.jwt) 2>valgrind-41.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token1.jwt) 2>valgrind-42.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token1.jwt) -P pub.jwks 2>valgrind-43.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token1.jwt) -K priv.jwks 2>valgrind-44.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token2.jwt) 2>valgrind-45.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token2.jwt) -K priv.jwks 2>valgrind-46.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token2.jwt) -P pub.jwks 2>valgrind-47.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token3.jwt) 2>valgrind-48.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token3.jwt) -K priv.jwks 2>valgrind-49.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token3.jwt) -P pub.jwks 2>valgrind-50.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token3.jwt) -P pub.jwks -K priv.jwks 2>valgrind-51.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token4.jwt) 2>valgrind-52.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token4.jwt) -K priv.jwks 2>valgrind-53.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token4.jwt) -P pub.jwks 2>valgrind-54.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token4.jwt) -P pub.jwks -K priv.jwks 2>valgrind-55.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token5.jwt) 2>valgrind-56.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token5.jwt) -K priv.jwks 2>valgrind-57.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token5.jwt) -P pub.jwks 2>valgrind-58.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token5.jwt) -P pub.jwks -K priv.jwks 2>valgrind-59.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token6.jwt) 2>valgrind-60.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token6.jwt) -K priv.jwks 2>valgrind-61.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token6.jwt) -P pub.jwks 2>valgrind-62.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token6.jwt) -P pub.jwks -K priv.jwks 2>valgrind-63.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token7.jwt) 2>valgrind-64.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token7.jwt) -K priv.jwks 2>valgrind-65.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token7.jwt) -P pub.jwks 2>valgrind-66.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token7.jwt) -P pub.jwks -K priv.jwks 2>valgrind-67.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token1.jwt) -P pub.jwks -H true -C false 2>valgrind-68.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token1.jwt) -P pub.jwks -H false -C false 2>valgrind-69.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token8.jwt) -W $(PASSWORD) 2>valgrind-70.txt $(VALGRIND_COMMAND) ./rnbyc -t $(shell cat token8.jwt) -W error 2>valgrind-71.txt || true $(VALGRIND_COMMAND) ./rnbyc -t $DPOP -S 2>valgrind-72.txt || true rhonabwy-1.1.13/tools/rnbyc/README.md000066400000000000000000000264361452472117100172010ustar00rootroot00000000000000# rnbyc: Rhonabwy command-line tool Copyright 2020-2022 Nicolas Mora This program is free software; you can redistribute it and/or modify it under the terms of the GPL3 License. ## Overview This command-line program can be used to: - Generate and/or parse keys and output the result in a JWKS or a public/private pair of JWKS files. - Parse, decrypt, and/or verify signature of a JWT, using given key - Serialize a JWT, the JWT can be signed, encrypted or nested ## Options Options available: ```shell -j --jwks Action: JWKS, parse or generate keys and output JWKS -g --generate Generate a key pair or a symmetric key - values available: RSA[key size] (default key size: 4096), EC256, EC384, EC521, Ed25519, Ed448, X25519, X448, oct[key size] (default key size: 128 bits) -i --stdin Reads key to parse from stdin -f --in-file Reads key to parse from a file -k --key-id Specifies the key-id to add to the current key -a --alg Action: JWKS - Specifies the alg value to add to the current key Action: Serialize - Specifies the alg value to sign the token -e --enc Specifies the enc value to encrypt the token (default A128CBC) -l --enc-alg Specifies the encryption algorithm for key management of the token -o --out-file Specifies the output file for the private keys (or all the keys if no public file is specified) in the JWKS -p --out-file-public Specifies the output file for the public keys in the JWKS -n --indent JWKS output spaces indentation: 0 is compact mode, default is 2 spaces indent -x --split Split JWKS output in public and private keys -t --parse-token Action: Parse token -s --serialize-token Action: serialize given claims in a token -H --header Display header of a parsed token -C --claims Display claims of a parsed token, default true -P --public-key Specifies the public key to for key management encryption or signature verification Public key must be in JWKS format and can be either a JWKS string or a path to a JWKS file -K --private-key Specifies the private key to for key management decryption or signature generation Public key must be in JWKS format and can be either a JWKS string or a path to a JWKS file -W --password Specifies the password for key management encryption/decryption using PBES2 alg or signature generation/verification using HS alg -u --x5u-flags Set x5u flags to retrieve online certificate, values available are: cert: ignore server certificate errors (self-signed, expired, etc.) follow: follow jwks_uri redirection if any values can be contatenated, e.g. --x5u-flags cert,follow -v --version Print rnbyc's current version -h --help Print this message -d --debug Display debug messages ``` ## Examples Here are some examples on how to use rnbyc ### Parses a X509 certificate file in PEM format and outputs a JWKS ```shell $ rnbyc -j -f /path/to/certificate.crt { "keys": [ { "kty": "RSA", "n": "AKe2TcuJhv-r1BBl7Z-TqgxILj70q7ckFcDLNS_2ksBR-UkCnrI8UsBBfejZFDCztt29x-AmWJanMsCv01kZsasOVwWSwteg9BAPmFTsP6LjNH2Lye-vTJ06uG_4yHDt3csgaypf_1HSq89u3jtxEXb-52ECjR-gMAIWFju9aPG2dTP9SjUuhN8RhWdHnQxqEbpaecYTDinWJ8qddtHeL1HbbkHQaKOeh2s0Zi8ylp65QkHp892n9n3yvtmspYhjoC0tpj4JZSCcSmfGoCBvJSqhh7OYOWtAmLADUgyIt5tXw2AQjEgZ1bs-SZrCjBFS9yBH7_nDHRO9eSxBFZbhLZG8wauML74hdyZAXYLHtV537tdO50pKScBK-_NYhIocSqlzFshgKkvz3OxdfX3zKr-Nrrbjv55dT6woY-wBl876t_ntQhJyGV-4MboRuO7OAlNdaeumoAAoUHX6zQ7xAdTyEU-p8CEkZbOH6V95jtCQ3le2d6oAWU2E7LRgyiQQ1w", "e": "AQAB", "kid": "yy4hDdTpyRau82hjUv-JWFwjGfqAxBs8qVH87fgdcOE", "x5c": [ "MIIEJjCCAo6gAwIBAgIUSbEidpFdnCljFBk1LLqjmYfax3owDQYJKoZIhvcNAQELBQAwLDEVMBMGA1UEAwwMZ2xld2x3eWRfd3d3MRMwEQYDVQQKEwpiYWJlbG91ZXN0MB4XDTIwMDUzMDE3MDk1NVoXDTIyMDQzMDE3MDk1NVowLDEVMBMGA1UEAwwMZ2xld2x3eWRfd3d3MRMwEQYDVQQKEwpiYWJlbG91ZXN0MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAp7ZNy4mG/6vUEGXtn5OqDEguPvSrtyQVwMs1L/aSwFH5SQKesjxSwEF96NkUMLO23b3H4CZYlqcywK/TWRmxqw5XBZLC16D0EA+YVOw/ouM0fYvJ769MnTq4b/jIcO3dyyBrKl//UdKrz27eO3ERdv7nYQKNH6AwAhYWO71o8bZ1M/1KNS6E3xGFZ0edDGoRulp5xhMOKdYnyp120d4vUdtuQdBoo56HazRmLzKWnrlCQenz3af2ffK+2ayliGOgLS2mPgllIJxKZ8agIG8lKqGHs5g5a0CYsANSDIi3m1fDYBCMSBnVuz5JmsKMEVL3IEfv+cMdE715LEEVluEtkbzBq4wvviF3JkBdgse1Xnfu107nSkpJwEr781iEihxKqXMWyGAqS/Pc7F19ffMqv42utuO/nl1PrChj7AGXzvq3+e1CEnIZX7gxuhG47s4CU11p66agAChQdfrNDvEB1PIRT6nwISRls4fpX3mO0JDeV7Z3qgBZTYTstGDKJBDXAgMBAAGjQDA+MAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUUktENOwWOjO+sDBnvyWGDmCVxQUwDQYJKoZIhvcNAQELBQADggGBAJI6N3YtfkdfZNv3NWPKGnSn7dXwFETk0PiBsURIv4B8DWxT4mtUGT6/x+ElVB//TIaK7P93uhmpZCM3DxMQCy8jR/ecA54cA+mAjQD2/4tBf2oRG34SfOsIW11ZPwfm3DRh95kZbjC4xCKGlCn6t/df/4CCDaLYPMReemy/3FynFxIO95hNV2+CPt1vzcDZfCkoBUoeN9b5q8nIXenajs3Cj4+w5Moiju0Ucg8X7tsTEjVre5M4Vtbc8BtvBOZ/qAS0Di2G1OXjkHBTMdIkcp/cHnm2f8rW3MljWowHSdu2dVYnkTyeqme1q7c613zdKp8YR0JR/ICxlwQQcHoxrFpok3dk//CVdDewcFG1KztJm458ppikOts9zjtvxlSU4diff3ofXdvVvjoYRkL1+89enCavLsaSqapUS8Jzz6BZrIUGWMDRoUZzRY41xLc2hqmABQSKNI8d1NE1sxmENS/YePS909uD4C9KRWY0z5x6/+LkRPRP0IkhHZXcMp+bIw==" ] } ] } ``` ### Generates a ECDSA 256 bits key pair in a single JWKS and specifies the kid ```shell $ rnbyc -j -g ec256 -k key1 { "keys": [ { "kty": "EC", "x": "AN64-jEEs_0zQfuUJI-9Rik6hkYMrIDHzSUfT3jlrA-q", "y": "APmN2Hk4SxihpBzQAZRVHlpxJS6O_0q-k8JgCcN-hj88", "d": "BvC2P98BQsYiMHqPqqfsguXe2Vl92JmZnB6Pj0jTHsM", "crv": "P-256", "kid": "key-1", "alg": "ES256" }, { "kty": "EC", "x": "AN64-jEEs_0zQfuUJI-9Rik6hkYMrIDHzSUfT3jlrA-q", "y": "APmN2Hk4SxihpBzQAZRVHlpxJS6O_0q-k8JgCcN-hj88", "crv": "P-256", "kid": "key-1", "alg": "ES256" } ] } ``` ### Parses a X509 private and public key files, generates a RSA 2048 key pair, and generates a 384 bits oct key, specifies the kid, the alg and the enc value, and splits the result into separate public and private JWKS. ```shell $ rnbyc -j -f /path/to/certificate.crt ``` ### Serializes a claims into signed JWT using RS256 alg and the specified private RSA key ```shell $ rnbyc -s '{"aud":"xyz123","nonce":"nonce1234"}' -K priv.jwks -a RS256 ``` ### Serializes a claims into encrypted JWT using RSA1_5 alg, A256GCM enc and the specified public RSA key ```shell $ rnbyc -s '{"aud":"xyz123","nonce":"nonce1234"}' -P pub.jwks -l RSA1_5 -e A256GCM ``` ### Serializes a claims into encrypted JWT using PBES2-HS256+A128KW alg, A256GCM enc and the specified password ```shell $ rnbyc -s '{"aud":"xyz123","nonce":"nonce1234"}' -W ThisIsThePassword -l PBES2-HS256+A128KW -e A256GCM ``` ### Serializes a claims into nested JWT using RS256 signatur alg, RSA1_5 encryption alg, A256GCM enc and the specified public RSA key ```shell $ rnbyc -s '{"aud":"xyz123","nonce":"nonce1234"}' -P pub.jwks -l RSA1_5 -e A256GCM -K priv.jwks -a RS256 ``` ### Parses a signed JWT to display claims ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjJZcXVEeXlNamJvWU4xSkU2TWVQQWVORk5lTzJUN0thTDcydTRQcUYySTgifQ.eyJhdWQiOiJ4eXoxMjMiLCJub25jZSI6Im5vbmNlMTIzNCJ9.ARpZkLEDAMLDfbcdowyHeb7fg00U06NHRnXCn2SiDMy1wE9SGJT3br-til-BXHJ0HoiSZ4HGhgTEaRf317bhy8jhHHVSJngWSncBxXzNe8cJ3A-bXZJBeTo5wKmxcwqgen744rAG5cmszC0KYR0rAXoqFDgPxxmw-EiFvgOfwn-COUS_ofdruc3BPyK-wuMNFMjqaQMi5RnTPuQZkSmmJkHGoRkAl0oafkKVvOL9VvO29It_b5Sk6uAHViczSY7A2v9oCQvGXML6aN8fqqQivM3ArCxWaDRXrWzO22SL3Qy11blrrCh-JJmKTcrHUjx2Ozacy1ecVXwc__h9Kn_AtA ``` ### Parses a signed JWT to display header only ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjJZcXVEeXlNamJvWU4xSkU2TWVQQWVORk5lTzJUN0thTDcydTRQcUYySTgifQ.eyJhdWQiOiJ4eXoxMjMiLCJub25jZSI6Im5vbmNlMTIzNCJ9.ARpZkLEDAMLDfbcdowyHeb7fg00U06NHRnXCn2SiDMy1wE9SGJT3br-til-BXHJ0HoiSZ4HGhgTEaRf317bhy8jhHHVSJngWSncBxXzNe8cJ3A-bXZJBeTo5wKmxcwqgen744rAG5cmszC0KYR0rAXoqFDgPxxmw-EiFvgOfwn-COUS_ofdruc3BPyK-wuMNFMjqaQMi5RnTPuQZkSmmJkHGoRkAl0oafkKVvOL9VvO29It_b5Sk6uAHViczSY7A2v9oCQvGXML6aN8fqqQivM3ArCxWaDRXrWzO22SL3Qy11blrrCh-JJmKTcrHUjx2Ozacy1ecVXwc__h9Kn_AtA -H -C false ``` ### Parses a signed JWT to verify the signature and display claims ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjJZcXVEeXlNamJvWU4xSkU2TWVQQWVORk5lTzJUN0thTDcydTRQcUYySTgifQ.eyJhdWQiOiJ4eXoxMjMiLCJub25jZSI6Im5vbmNlMTIzNCJ9.ARpZkLEDAMLDfbcdowyHeb7fg00U06NHRnXCn2SiDMy1wE9SGJT3br-til-BXHJ0HoiSZ4HGhgTEaRf317bhy8jhHHVSJngWSncBxXzNe8cJ3A-bXZJBeTo5wKmxcwqgen744rAG5cmszC0KYR0rAXoqFDgPxxmw-EiFvgOfwn-COUS_ofdruc3BPyK-wuMNFMjqaQMi5RnTPuQZkSmmJkHGoRkAl0oafkKVvOL9VvO29It_b5Sk6uAHViczSY7A2v9oCQvGXML6aN8fqqQivM3ArCxWaDRXrWzO22SL3Qy11blrrCh-JJmKTcrHUjx2Ozacy1ecVXwc__h9Kn_AtA -P pub.jwks ``` ### Parses a signed JWT with the public key included in the header and verifies the signature ```shell $ rnbyc -t eyJ0eXAiOiJkcG9wK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwieCI6Imw4dEZyaHgtMzR0VjNoUklDUkRZOXpDa0RscEJoRjQyVVFVZldWQVdCRnMiLCJ5IjoiOVZFNGpmX09rX282NHpiVFRsY3VOSmFqSG10NnY5VERWclUwQ2R2R1JEQSIsImNydiI6IlAtMjU2In19.eyJqdGkiOiItQndDM0VTYzZhY2MybFRjIiwiaHRtIjoiUE9TVCIsImh0dSI6Imh0dHBzOi8vc2VydmVyLmV4YW1wbGUuY29tL3Rva2VuIiwiaWF0IjoxNTYyMjYyNjE2fQ.2-GxA6T8lP4vfrg8v-FdWP0A0zdrj8igiMLvqRMUvwnQg4PtFLbdLXiOSsX0x7NVY-FNyJK70nfbV37xRZT3Lg -S ``` ### Parses an encrypted JWT to decrypt its content and display claims ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiMllxdUR5eU1qYm9ZTjFKRTZNZVBBZU5GTmVPMlQ3S2FMNzJ1NFBxRjJJOCJ9.cK5l8oRaOqCYB1G-z06B2F9aJupLIrKHcwjOn-WhImMn9Vy5kF0USVIPHVHDoUcOISG7uA_tfHM0bkWyb-wWu4UW3jrWLAWltGOQQZEbLKYrLEJFmqqBeMKJ01_3bpbRYIRrqB96N50HJKu9EH_8c5OL3d-m9QIhNh37wa7Vu63tZgLlYVEHoGVOZF0eBWV-fWH-My76Sp5ZA3XsR5BjmbDOzzutFWlucMEjWS8GeSM5ibkkTjSJCsY7PpghQA8LUKshLY4PifwyBmlc51GzKOTkFBtxeDx4ixAMSsTdc72sN9-zjr733jp3DAwaxfjQC5QxDGeAI1DG53iEqD8Y0g.I_Ei-Ioi-IH3MENa.fJfo6fssSJ-6LNZHwlYH2t0Rg4w1vKTLrMo54QswuRenCfoBOBcUaIBD6Y-Id_Ms.AeiVJjZFR-w-c5wiyBmcGw -K priv.jwks ``` ### Parses an encrypted JWT to decrypt its content and display claims using a password ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJwMnMiOiJOQjVuUnJlUko1cyIsInAyYyI6NDA5NiwiZW5jIjoiQTI1NkdDTSJ9.w0v_Pu139guygbyCQExbb_AJJlEAFRikDT81JOyVBXeWrMSlcDgWRg.b6-7JtOdIzvbUTY4.j-R30XnnMUxu7A7ZE1zExv9cRZq5Cg9FbASqgvGyVSPPsrfg.KKsXDsnNDSmvz_atWvuNGg -W ThisIsThePassword ``` ### Parses a nested JWT to decrypt its content, verify signature and display header and claims ```shell $ rnbyc -t eyJ0eXAiOiJKV1QiLCJjdHkiOiJKV1QiLCJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiMllxdUR5eU1qYm9ZTjFKRTZNZVBBZU5GTmVPMlQ3S2FMNzJ1NFBxRjJJOCJ9.r-benEaVi8BRAKPDGTJl48L0LqjnDCZbC_krSbyjpy-iN0Fhli0R724uBkr69aU6L1MceK2RtS30FwsUrOx8ySJmC3FuEf4UgqGsrlAwa0PnkIgxCKld5x1YRKIkOL01HXYgjnlU45PCtknnST7f4TWbBh24_gsKQXoiC1_viqavsk0aGBkLnAfmIAuEgMvroBqcX8S9XaLW8z3MzZ9u-9CyeqYSjQns_FlCBqqDDQTmf7WPZf0Yr3TxzdDvHR60Cf0cS2kbMh6bYAI6IO7rh63mALuxt64W2on-Gf8zAPx8MSkiiRkDqQurqgxGDZLOFD4xF3R7bm2yF6GtSnfbAQ.lVRM-vp5sP5pmT8C.1AdxJPtT3RDktUm_bZeWok6gWJBBm5_lm33eKM5kF4wGj_C9Q2jtoXgdUeaw7cojQdCVCIAFZs67dOfPl8Hj0SnJq0RGV2XTpmmWeuFglyQKur7H65SLzoQf6MHJVlrYon3S5TD6d82WvmJfOh2gNGcyo9Yj1fLxwr3DLGmV_5YZa46lqiT00VPKbmuLYO_wm4kw4A6juQCqholzX1htzd-L4IMMc3FdWwtTu7rCT7Fg9acRXB0F-Bhjmc3s9nLJNFysfdG2qxvWcgK8-uin0gePUm1kpGGEoUHMoXQfc0vA8cs2QlIzXgMKpSHM-hYkVWtyMFnRP0rbql0GysEwGS70Tmmbp378XnpHyZnF9ZSIwvyPkeefVWG4GsiguL2yBKZ4QFzWCkyKGvXg4MfAJnsY7xGfP7QSTlfStPcnslij0xAVw0ilzSW8q3TpEUsDO3bpbENgIxQEjFoHFzm3vycB-071RYxEeNHHki00f3nl_VQRVhiOWMD6mYsf_dx2R7vmu-wF_mc-gzO_jk5lmQG9ZW0dWI-ofp9aFqayjLTQ_IbSofLlIHhvW5tlrV0DOdgMpfcYH6h0rA9T7ur9GRmcRPDr9G1MAY8vmpKhYlk38sOaql5W3icjjdXJLo9KTuk6FJ1Hed8ZcYiXgLlA5nhmEtfGTahL4VHgwVwWlFc.H-esLtlVR9GM9Hn4EnmxBQ -K priv.jwks -P pub.jwks -H true ``` rhonabwy-1.1.13/tools/rnbyc/rnbyc.1000066400000000000000000000072211452472117100171100ustar00rootroot00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. .TH RNBYC "1" "September 2023" "rnbyc 1.1.8" "User Commands" .SH NAME rnbyc \- JWK and JWT parser and generator .SH DESCRIPTION rnbyc \- JWK/JWKS parser and generator, JWT parser and serializer, supports signed, encrypted and nested JWTs .PP Version 1.1.8 .SH COPYRIGHT Copyright 2020\-2022 Nicolas Mora .PP This program is free software; you can redistribute it and/or modify it under the terms of the GPL 3 .PP Command\-line options: .PP \fB\-j\fR \fB\-\-jwks\fR .IP Action: JWKS, parse or generate keys and output JWKS .PP \fB\-g\fR \fB\-\-generate\fR .IP Generate a key pair or a symmetric key \- values available: RSA[key size] (default key size: 4096), EC256, EC384, EC521, Ed25519, Ed448, X25519, X448, oct[key size] (default key size: 128 bits) .PP \fB\-i\fR \fB\-\-stdin\fR .IP Reads key to parse from stdin .PP \fB\-f\fR \fB\-\-in\-file\fR .IP Reads key to parse from a file .PP \fB\-k\fR \fB\-\-key\-id\fR .IP Specifies the key\-id to add to the current key .PP \fB\-a\fR \fB\-\-alg\fR .IP Action: JWKS \- Specifies the alg value to add to the current key Action: Serialize \- Specifies the alg value to sign the token .PP \fB\-e\fR \fB\-\-enc\fR .IP Specifies the enc value to encrypt the token (default A128CBC) .PP \fB\-l\fR \fB\-\-enc\-alg\fR .IP Specifies the encryption algorithm for key management of the token .PP \fB\-o\fR \fB\-\-out\-file\fR .IP Specifies the output file for the private keys (or all the keys if no public file is specified) in the JWKS .PP \fB\-p\fR \fB\-\-out\-file\-public\fR .IP Specifies the output file for the public keys in the JWKS .PP \fB\-n\fR \fB\-\-indent\fR .IP JWKS output spaces indentation: 0 is compact mode, default is 2 spaces indent .PP \fB\-F\fR \fB\-\-format\fR .IP Output format, values available are JWK (default), PEM or DER .PP \fB\-x\fR \fB\-\-split\fR .IP Split JWKS output in public and private keys .PP \fB\-t\fR \fB\-\-parse\-token\fR .IP Action: Parse token .PP \fB\-s\fR \fB\-\-serialize\-token\fR .IP Action: serialize given claims in a token .PP \fB\-H\fR \fB\-\-header\fR .IP Display header of a parsed token .PP \fB\-C\fR \fB\-\-claims\fR .IP Display claims of a parsed token, default true .PP \fB\-P\fR \fB\-\-public\-key\fR .IP Specifies the public key for key management encryption or signature verification Public key must be in JWKS format and can be either a JWKS string or a path to a JWKS file .PP \fB\-K\fR \fB\-\-private\-key\fR .IP Specifies the private key for key management decryption or signature generation Public key must be in JWKS format and can be either a JWKS string or a path to a JWKS file .PP \fB\-S\fR \fB\-\-self\-signed\fR .IP Verifies the JWT signature if the signed JWT has its public key included in its header as 'jwk', 'x5c' or 'x5u' parameter .PP \fB\-W\fR \fB\-\-password\fR .IP Specifies the password for key management encryption/decryption using PBES2 alg or signature generation/verification using HS alg .PP \fB\-u\fR \fB\-\-x5u\-flags\fR .IP Set x5u flags to retrieve online certificate, values available are: .IP cert: ignore server certificate errors (self\-signed, expired, etc.) follow: follow jwks_uri redirection if any values can be contatenated, e.g. \fB\-\-x5u\-flags\fR cert,follow .PP \fB\-v\fR \fB\-\-version\fR .IP Print rnbyc's current version .PP \fB\-h\fR \fB\-\-help\fR .IP Print this message .PP \fB\-d\fR \fB\-\-debug\fR .IP Display debug messages .SH "SEE ALSO" The full documentation for .B rnbyc is maintained as a Texinfo manual. If the .B info and .B rnbyc programs are properly installed at your site, the command .IP .B info rnbyc .PP should give you access to the complete manual. rhonabwy-1.1.13/tools/rnbyc/rnbyc.c000066400000000000000000001314731452472117100172010ustar00rootroot00000000000000/** * * rnbyc: Rhonabwy command-line tool * * Copyright 2020-2022 Nicolas Mora * * Command-line tool to manipulate JWK, JWKS, JWE, JWS and JWT * - Generates random JWK using the specified algorithm * - Generates random JWKS using the specified algorithm * - Parses cryptographic key to JWK, input format are: * * JWK * * JWKS * * X509 PEM * * X509 DER * - Parses JWE, JWS or JWT using key if possible * * verify signature * * decrypt content * * verify claims * - Serialize JWE, JWS or JWT based on the key and the content * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU GENERAL PUBLIC LICENSE * License as published by the Free Software Foundation; * version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU GENERAL PUBLIC LICENSE for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see . * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _RNBYC_VERSION_ "1.1.8" #define R_RSA_DEFAULT_SIZE 4096 #define R_OCT_DEFAULT_SIZE 128 #define R_ACTION_NONE 0 #define R_ACTION_JWKS_OUT 1 #define R_ACTION_PARSE_TOKEN 2 #define R_ACTION_SERIALIZE_TOKEN 3 #define RNBYC_FORMAT_JWK 0 #define RNBYC_FORMAT_PEM 1 #define RNBYC_FORMAT_DER 2 static void print_help(FILE * output) { fprintf(output, "\nrnbyc - JWK/JWKS parser and generator, JWT parser and serializer, supports signed, encrypted and nested JWTs\n"); fprintf(output, "\n"); fprintf(output, "Version %s\n", _RNBYC_VERSION_); fprintf(output, "\n"); fprintf(output, "Copyright 2020-2022 Nicolas Mora \n"); fprintf(output, "\n"); fprintf(output, "This program is free software; you can redistribute it and/or\n"); fprintf(output, "modify it under the terms of the GPL 3\n"); fprintf(output, "\n"); fprintf(output, "Command-line options:\n"); fprintf(output, "\n"); fprintf(output, "-j --jwks\n"); fprintf(output, "\tAction: JWKS, parse or generate keys and output JWKS\n"); fprintf(output, "-g --generate \n"); fprintf(output, "\tGenerate a key pair or a symmetric key\n"); fprintf(output, "\t - values available:\n"); #if NETTLE_VERSION_NUMBER >= 0x03060e fprintf(output, "\tRSA[key size] (default key size: 4096), EC256, EC384, EC521, Ed25519, Ed448, X25519, X448, oct[key size] (default key size: 128 bits)\n"); #elif NETTLE_VERSION_NUMBER >= 0x030600 fprintf(output, "\tRSA[key size] (default key size: 4096), EC256, EC384, EC521, Ed25519, X25519, oct[key size] (default key size: 128 bits)\n"); #else fprintf(output, "\tRSA[key size] (default key size: 4096), EC256, EC384, EC521, oct[key size] (default key size: 128 bits)\n"); #endif fprintf(output, "-i --stdin\n"); fprintf(output, "\tReads key to parse from stdin\n"); fprintf(output, "-f --in-file\n"); fprintf(output, "\tReads key to parse from a file\n"); fprintf(output, "-k --key-id\n"); fprintf(output, "\tSpecifies the key-id to add to the current key\n"); fprintf(output, "-a --alg\n"); fprintf(output, "\tAction: JWKS - Specifies the alg value to add to the current key\n"); fprintf(output, "\tAction: Serialize - Specifies the alg value to sign the token\n"); fprintf(output, "-e --enc\n"); fprintf(output, "\tSpecifies the enc value to encrypt the token (default A128CBC)\n"); fprintf(output, "-l --enc-alg\n"); fprintf(output, "\tSpecifies the encryption algorithm for key management of the token\n"); fprintf(output, "-o --out-file\n"); fprintf(output, "\tSpecifies the output file for the private keys (or all the keys if no public file is specified) in the JWKS\n"); fprintf(output, "-p --out-file-public\n"); fprintf(output, "\tSpecifies the output file for the public keys in the JWKS\n"); fprintf(output, "-n --indent\n"); fprintf(output, "\tJWKS output spaces indentation: 0 is compact mode, default is 2 spaces indent\n"); fprintf(output, "-F --format\n"); fprintf(output, "\tOutput format, values available are JWK (default), PEM or DER\n"); fprintf(output, "-x --split\n"); fprintf(output, "\tSplit JWKS output in public and private keys\n"); fprintf(output, "-t --parse-token\n"); fprintf(output, "\tAction: Parse token\n"); fprintf(output, "-s --serialize-token\n"); fprintf(output, "\tAction: serialize given claims in a token\n"); fprintf(output, "-H --header\n"); fprintf(output, "\tDisplay header of a parsed token\n"); fprintf(output, "-C --claims\n"); fprintf(output, "\tDisplay claims of a parsed token, default true\n"); fprintf(output, "-P --public-key\n"); fprintf(output, "\tSpecifies the public key for key management encryption or signature verification\n"); fprintf(output, "\tPublic key must be in JWKS format and can be either a JWKS string or a path to a JWKS file\n"); fprintf(output, "-K --private-key\n"); fprintf(output, "\tSpecifies the private key for key management decryption or signature generation\n"); fprintf(output, "\tPublic key must be in JWKS format and can be either a JWKS string or a path to a JWKS file\n"); fprintf(output, "-S --self-signed\n"); fprintf(output, "\tVerifies the JWT signature if the signed JWT has its public key included in its header\n"); fprintf(output, "\tas 'jwk', 'x5c' or 'x5u' parameter\n"); fprintf(output, "-W --password\n"); fprintf(output, "\tSpecifies the password for key management encryption/decryption using PBES2 alg or signature generation/verification using HS alg\n"); fprintf(output, "-u --x5u-flags\n"); fprintf(output, "\tSet x5u flags to retrieve online certificate, values available are:\n"); fprintf(output, "\t\tcert: ignore server certificate errors (self-signed, expired, etc.)\n"); fprintf(output, "\t\tfollow: follow jwks_uri redirection if any\n"); fprintf(output, "\t\tvalues can be contatenated, e.g. --x5u-flags cert,follow\n"); fprintf(output, "-v --version\n"); fprintf(output, "\tPrint rnbyc's current version\n"); fprintf(output, "-h --help\n"); fprintf(output, "\tPrint this message\n\n"); fprintf(output, "-d --debug\n"); fprintf(output, "\tDisplay debug messages\n\n"); } static int write_file_content(const char * file_path, const char * content, size_t content_len) { FILE * f; int ret; f = fopen (file_path, "w+"); if (f) { if (fwrite(content, 1, content_len, f) > 0 && fwrite("\n", 1, 1, f) > 0) { ret = 0; } else { ret = ENOENT; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); ret = EACCES; } return ret; } static char * get_file_content(const char * file_path) { char * buffer = NULL; size_t length, res; FILE * f; f = fopen (file_path, "rb"); if (f) { fseek (f, 0, SEEK_END); length = (size_t)ftell (f); fseek (f, 0, SEEK_SET); buffer = o_malloc((length+1)*sizeof(char)); if (buffer) { res = fread (buffer, 1, length, f); if (res != length) { fprintf(stderr, "fread warning, reading %zu while expecting %zu", res, length); } // Add null character at the end of buffer, just in case buffer[length] = '\0'; } fclose (f); } else { fprintf(stderr, "error opening file %s\n", file_path); } return buffer; } static char * get_stdin_content() { int size = 100; char * out = NULL, buffer[size]; ssize_t length = 0, read_length; while ((read_length = read(0, buffer, (size_t)size)) > 0) { out = o_realloc(out, (size_t)(length+read_length+1)); memcpy(out+length, buffer, (size_t)read_length); length += read_length; out[length] = '\0'; } return out; } static int jwk_generate(jwks_t * jwks_privkey, jwks_t * jwks_pubkey, json_t * j_element) { jwk_t * jwk_priv = NULL, * jwk_pub = NULL; unsigned char * oct = NULL, oct_kid[16] = {0}, oct_kid_b64[32] = {0}; size_t oct_kid_b64_len = 0; const char * type = json_string_value(json_object_get(j_element, "type")); int ret = 0; json_int_t bits; if (r_jwk_init(&jwk_priv) == RHN_OK && r_jwk_init(&jwk_pub) == RHN_OK) { if (0 == o_strcmp("RSA", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_RSA, (unsigned int)json_integer_value(json_object_get(j_element, "bits")), json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } } else if (0 == o_strcasecmp("EC256", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_EC, 256, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "ES256"); r_jwk_set_property_str(jwk_pub, "alg", "ES256"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } } else if (0 == o_strcasecmp("EC384", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_EC, 384, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "ES384"); r_jwk_set_property_str(jwk_pub, "alg", "ES384"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } } else if (0 == o_strcasecmp("EC521", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_EC, 521, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "ES512"); r_jwk_set_property_str(jwk_pub, "alg", "ES512"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } #if NETTLE_VERSION_NUMBER >= 0x030600 } else if (0 == o_strcasecmp("Ed25519", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_EDDSA, 256, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "EdDSA"); r_jwk_set_property_str(jwk_pub, "alg", "EdDSA"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } } else if (0 == o_strcasecmp("X25519", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_ECDH, 256, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "X25519"); r_jwk_set_property_str(jwk_pub, "alg", "X25519"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } #endif #if NETTLE_VERSION_NUMBER >= 0x03060e } else if (0 == o_strcasecmp("Ed448", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_EDDSA, 448, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "EdDSA"); r_jwk_set_property_str(jwk_pub, "alg", "EdDSA"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } } else if (0 == o_strcasecmp("X448", type)) { r_jwk_generate_key_pair(jwk_priv, jwk_pub, R_KEY_TYPE_ECDH, 448, json_string_value(json_object_get(j_element, "kid"))); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } else { r_jwk_set_property_str(jwk_priv, "alg", "X25519"); r_jwk_set_property_str(jwk_pub, "alg", "X25519"); } r_jwks_append_jwk(jwks_privkey, jwk_priv); if (jwks_pubkey != NULL) { r_jwks_append_jwk(jwks_pubkey, jwk_pub); } else { r_jwks_append_jwk(jwks_privkey, jwk_pub); } #endif } else if (0 == o_strcasecmp("oct", type)) { bits = json_integer_value(json_object_get(j_element, "bits")); bits += (bits%8); oct = o_malloc((size_t)bits/8); gnutls_rnd(GNUTLS_RND_KEY, oct, (size_t)bits/8); r_jwk_import_from_symmetric_key(jwk_priv, oct, (size_t)bits/8); if (json_string_length(json_object_get(j_element, "alg"))) { r_jwk_set_property_str(jwk_priv, "alg", json_string_value(json_object_get(j_element, "alg"))); r_jwk_set_property_str(jwk_pub, "alg", json_string_value(json_object_get(j_element, "alg"))); } if (json_string_value(json_object_get(j_element, "kid")) != NULL) { r_jwk_set_property_str(jwk_priv, "kid", json_string_value(json_object_get(j_element, "kid"))); } else { gnutls_rnd(GNUTLS_RND_KEY, oct_kid, 16); o_base64url_encode(oct_kid, 16, oct_kid_b64, &oct_kid_b64_len); oct_kid_b64[oct_kid_b64_len] = '\0'; r_jwk_set_property_str(jwk_priv, "kid", (const char *)oct_kid_b64); } r_jwks_append_jwk(jwks_privkey, jwk_priv); o_free(oct); } else { fprintf(stderr, "Invalid key type"); ret = EINVAL; } } else { ret = ENOMEM; } r_jwk_free(jwk_priv); r_jwk_free(jwk_pub); return ret; } static int jwks_parse_str(jwks_t * jwks_priv, jwks_t * jwks_pub, const char * in, const char * kid, const char * alg, int x5u_flags) { jwks_t * jwks = NULL; jwk_t * jwk = NULL; int ret, key_type; size_t i; if (r_jwks_init(&jwks) == RHN_OK && r_jwks_import_from_json_str(jwks, in) == RHN_OK) { for (i=0; ijws) { j_value = r_jws_get_full_header_json_t(jwt->jws); str_value = json_dumps(j_value, (size_t)(JSON_INDENT(indent)|JSON_SORT_KEYS)); printf("%s\n", str_value); o_free(str_value); json_decref(j_value); } } if (show_claims) { str_value = NULL; j_value = r_jwt_get_full_claims_json_t(jwt); if (j_value != NULL) { str_value = json_dumps(j_value, (size_t)(JSON_INDENT(indent)|JSON_SORT_KEYS)); printf("%s\n", str_value); o_free(str_value); json_decref(j_value); } } } else if (res == RHN_ERROR_PARAM) { fprintf(stderr, "Invalid token\n"); ret = EINVAL; } else { fprintf(stderr, "Error parsing token\n"); ret = EINVAL; } } r_jwt_free(jwt); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); o_free(token_dup); return ret; } static int serialize_token(const char * claims, int x5u_flags, const char * str_jwks_pubkey, const char * str_jwks_privkey, const char * password, const char * alg, const char * enc, const char * enc_alg) { jwt_t * jwt = NULL; jwks_t * jwks_pubkey = NULL, * jwks_privkey = NULL; jwk_t * jwk_password; char * token = NULL, * content = NULL; int ret = 0; if (r_jwt_init(&jwt) == RHN_OK) { if (r_jwt_set_full_claims_json_str(jwt, claims) == RHN_OK) { if (r_jwks_init(&jwks_pubkey) == RHN_OK) { if (o_strlen(str_jwks_pubkey) && str_jwks_pubkey[0] == '{') { if (r_jwks_import_from_json_str(jwks_pubkey, str_jwks_pubkey) != RHN_OK) { fprintf(stderr, "Invalid jwks_pubkey\n"); ret = EINVAL; } } else if (o_strlen(str_jwks_pubkey)) { content = get_file_content(str_jwks_pubkey); if (r_jwks_import_from_json_str(jwks_pubkey, content) != RHN_OK) { fprintf(stderr, "Invalid jwks_pubkey path or content\n"); ret = EAGAIN; } o_free(content); } else if (o_strlen(password) && o_strlen(enc_alg)) { r_jwk_init(&jwk_password); if (r_jwk_import_from_password(jwk_password, password) != RHN_OK) { fprintf(stderr, "Error parsing password\n"); } else { if (r_jwks_append_jwk(jwks_pubkey, jwk_password) != RHN_OK) { fprintf(stderr, "Error importing password\n"); } } r_jwk_free(jwk_password); } } if (r_jwks_init(&jwks_privkey) == RHN_OK) { if (o_strlen(str_jwks_privkey) && str_jwks_privkey[0] == '{') { if (r_jwks_import_from_json_str(jwks_privkey, str_jwks_privkey) != RHN_OK) { fprintf(stderr, "Invalid jwks_privkey\n"); ret = EINVAL; } } else if (o_strlen(str_jwks_privkey)) { content = get_file_content(str_jwks_privkey); if (r_jwks_import_from_json_str(jwks_privkey, content) != RHN_OK) { fprintf(stderr, "Invalid jwks_privkey path or content\n"); ret = EAGAIN; } o_free(content); } else if (o_strlen(password) && o_strlen(alg)) { r_jwk_init(&jwk_password); if (r_jwk_import_from_password(jwk_password, password) != RHN_OK) { fprintf(stderr, "Error parsing password\n"); } else { if (r_jwks_append_jwk(jwks_privkey, jwk_password) != RHN_OK) { fprintf(stderr, "Error importing password\n"); } } r_jwk_free(jwk_password); } } if (jwks_pubkey != NULL) { if (r_jwt_add_enc_jwks(jwt, NULL, jwks_pubkey) != RHN_OK) { fprintf(stderr, "Error setting public key\n"); ret = ENOMEM; } if (enc != NULL) { if (r_jwt_set_enc(jwt, r_str_to_jwa_enc(enc)) != RHN_OK) { fprintf(stderr, "Invalid enc value\n"); ret = EINVAL; } } else { r_jwt_set_enc(jwt, R_JWA_ENC_A128CBC); } if (enc_alg != NULL) { if (r_jwt_set_enc_alg(jwt, r_str_to_jwa_alg(enc_alg)) != RHN_OK) { fprintf(stderr, "Invalid enc_alg value\n"); ret = EINVAL; } } } if (jwks_privkey != NULL) { if (r_jwt_add_sign_jwks(jwt, jwks_privkey, NULL) != RHN_OK) { fprintf(stderr, "Error setting private key\n"); ret = ENOMEM; } if (alg != NULL) { if (r_jwt_set_sign_alg(jwt, r_str_to_jwa_alg(alg)) != RHN_OK) { fprintf(stderr, "Invalid alg value\n"); ret = EINVAL; } } } if (!ret) { if (r_jwks_size(jwks_pubkey) && r_jwks_size(jwks_privkey)) { token = r_jwt_serialize_nested(jwt, R_JWT_TYPE_NESTED_SIGN_THEN_ENCRYPT, NULL, x5u_flags, NULL, x5u_flags); } else if (r_jwks_size(jwks_pubkey) && !r_jwks_size(jwks_privkey)) { token = r_jwt_serialize_encrypted(jwt, NULL, x5u_flags); } else if (!r_jwks_size(jwks_pubkey) && r_jwks_size(jwks_privkey)) { token = r_jwt_serialize_signed(jwt, NULL, x5u_flags); } else if (o_strlen(password)) { token = r_jwt_serialize_encrypted(jwt, NULL, x5u_flags); } else { r_jwt_set_sign_alg(jwt, R_JWA_ALG_NONE); token = r_jwt_serialize_signed(jwt, NULL, x5u_flags); } } if (token == NULL) { fprintf(stderr, "Error serializing token\n"); ret = EINVAL; } else { printf("%s\n", token); } o_free(token); } else { fprintf(stderr, "Error setting JSON claims\n"); ret = EINVAL; } } r_jwt_free(jwt); r_jwks_free(jwks_pubkey); r_jwks_free(jwks_privkey); return ret; } int main (int argc, char ** argv) { int next_option, action = R_ACTION_NONE, ret = 0, has_stdin = 0, split_keys = 0, show_header = 0, show_claims = 1, self_signed = 0, x5u_flags = 0, debug_mode = 0, format = RNBYC_FORMAT_JWK; const char * short_options = "j::g:i::f:k:a:e:l:o:p:n:F:x::t:s:H::C:K:P:S::W:u:v::h::d::"; char * out_file = NULL, * out_file_public = NULL, * parsed_token = NULL, * str_token_public_key = NULL, * str_token_private_key = NULL, * password = NULL, * alg = NULL, * enc = NULL, * enc_alg = NULL, * claims = NULL; static const struct option long_options[]= { {"jwks", no_argument, NULL, 'j'}, {"generate", required_argument, NULL, 'g'}, {"stdin", no_argument, NULL, 'i'}, {"in-file", required_argument, NULL, 'f'}, {"key-id", required_argument, NULL, 'k'}, {"alg", required_argument, NULL, 'a'}, {"enc", required_argument, NULL, 'e'}, {"enc-alg", required_argument, NULL, 'l'}, {"out-file", required_argument, NULL, 'o'}, {"out-file-public", required_argument, NULL, 'p'}, {"indent", required_argument, NULL, 'n'}, {"format", no_argument, NULL, 'F'}, {"split", no_argument, NULL, 'x'}, {"parse-token", required_argument, NULL, 't'}, {"serialize-token", required_argument, NULL, 's'}, {"header", no_argument, NULL, 'H'}, {"claims", required_argument, NULL, 'C'}, {"public-key", required_argument, NULL, 'P'}, {"self-signed", required_argument, NULL, 'S'}, {"private-key", required_argument, NULL, 'K'}, {"password", required_argument, NULL, 'W'}, {"x5u-flags", required_argument, NULL, 'u'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {"debug", no_argument, NULL, 'd'}, {NULL, 0, NULL, 0} }; json_t * j_arguments = json_array(); unsigned long bits = 0; int indent = 2; jwa_alg j_alg = R_JWA_ALG_NONE; do { next_option = getopt_long(argc, argv, short_options, long_options, NULL); switch (next_option) { case 'j': if (action == R_ACTION_NONE) { action = R_ACTION_JWKS_OUT; } break; case 'g': if (action == R_ACTION_JWKS_OUT) { if (0 == o_strncasecmp(optarg, "RSA", o_strlen("RSA"))) { if (o_strlen(optarg) == o_strlen("RSA")) { json_array_append_new(j_arguments, json_pack("{sssssi}", "source", "generate", "type", "RSA", "bits", R_RSA_DEFAULT_SIZE)); } else if ((bits = strtoul(optarg+o_strlen("RSA"), NULL, 10)) >= 128) { json_array_append_new(j_arguments, json_pack("{sssssi}", "source", "generate", "type", "RSA", "bits", bits)); } else { fprintf(stderr, "--generate: Invalid argument\n"); ret = EINVAL; } } else if (0 == o_strcasecmp("EC256", optarg) || 0 == o_strcasecmp("EC384", optarg) || 0 == o_strcasecmp("EC521", optarg) || 0 == o_strcasecmp("Ed25519", optarg) || 0 == o_strcasecmp("X25519", optarg) || 0 == o_strcasecmp("X448", optarg)) { json_array_append_new(j_arguments, json_pack("{ssss}", "source", "generate", "type", optarg)); } else if (0 == o_strncasecmp(optarg, "oct", o_strlen("oct"))) { if (o_strlen(optarg) == o_strlen("oct")) { json_array_append_new(j_arguments, json_pack("{sssssi}", "source", "generate", "type", "oct", "bits", R_OCT_DEFAULT_SIZE)); } else if ((bits = strtoul(optarg+o_strlen("oct"), NULL, 10))) { json_array_append_new(j_arguments, json_pack("{sssssi}", "source", "generate", "type", "oct", "bits", bits)); } else { fprintf(stderr, "--generate: Invalid argument\n"); ret = EINVAL; } } else { fprintf(stderr, "--generate: Invalid argument\n"); ret = EINVAL; } } else { fprintf(stderr, "--generate: argument incompatible with parse or serialize action\n"); ret = EINVAL; } break; case 'i': if (has_stdin) { fprintf(stderr, "--stdin: can not use more than once\n"); ret = EINVAL; } else if (action == R_ACTION_JWKS_OUT) { json_array_append_new(j_arguments, json_pack("{ss}", "source", "stdin")); has_stdin = 1; } else { fprintf(stderr, "--stdin: argument incompatible with parse or serialize action\n"); ret = EINVAL; } break; case 'f': if (action == R_ACTION_JWKS_OUT) { json_array_append_new(j_arguments, json_pack("{ssss}", "source", "file", "path", optarg)); } else { fprintf(stderr, "--file: argument incompatible with parse or serialize action\n"); ret = EINVAL; } break; case 'k': if (json_array_size(j_arguments)) { json_object_set_new(json_array_get(j_arguments, json_array_size(j_arguments)-1), "kid", json_string(optarg)); } break; case 'o': out_file = o_strdup(optarg); break; case 'p': out_file_public = o_strdup(optarg); split_keys = 1; break; case 'F': if (action == R_ACTION_JWKS_OUT) { if (0 == o_strncasecmp(optarg, "JWK", o_strlen("JWK"))) { format = RNBYC_FORMAT_JWK; } else if (0 == o_strncasecmp(optarg, "PEM", o_strlen("PEM"))) { format = RNBYC_FORMAT_PEM; } else if (0 == o_strncasecmp(optarg, "DER", o_strlen("DER"))) { format = RNBYC_FORMAT_DER; } else { fprintf(stderr, "--format: Invalid format\n"); ret = EINVAL; } } else { fprintf(stderr, "--format: argument incompatible with parse or serialize action\n"); ret = EINVAL; } break; case 'x': split_keys = 1; break; case 'a': if ((j_alg = r_str_to_jwa_alg(optarg)) != R_JWA_ALG_NONE && j_alg != R_JWA_ALG_UNKNOWN) { if (action == R_ACTION_JWKS_OUT) { json_object_set_new(json_array_get(j_arguments, json_array_size(j_arguments)-1), "alg", json_string(optarg)); } else { o_free(alg); alg = o_strdup(optarg); } } else { fprintf(stderr, "--alg: argument invalid: %s\n", optarg); ret = EINVAL; } break; case 'e': if (r_str_to_jwa_enc(optarg) != R_JWA_ENC_UNKNOWN) { o_free(enc); enc = o_strdup(optarg); } else { fprintf(stderr, "--enc: argument invalid: %s\n", optarg); ret = EINVAL; } break; case 'l': if ((j_alg = r_str_to_jwa_alg(optarg)) != R_JWA_ALG_NONE && j_alg != R_JWA_ALG_UNKNOWN) { o_free(enc_alg); enc_alg = o_strdup(optarg); } else { fprintf(stderr, "--enc-alg: argument invalid: %s\n", optarg); ret = EINVAL; } break; case 'n': indent = (int)strtol(optarg, NULL, 10); break; case 't': action = R_ACTION_PARSE_TOKEN; parsed_token = o_strdup(optarg); break; case 's': action = R_ACTION_SERIALIZE_TOKEN; claims = o_strdup(optarg); break; case 'H': show_header = 1; break; case 'C': if (0 == o_strcasecmp("false", optarg) || 0 == o_strcasecmp("no", optarg) || 0 == o_strcmp("0", optarg)) { show_claims = 0; } else { show_claims = 1; } break; case 'K': str_token_private_key = o_strdup(optarg); break; case 'P': str_token_public_key = o_strdup(optarg); break; case 'S': self_signed = 1; break; case 'W': password = o_strdup(optarg); break; case 'u': if (o_strcasestr(optarg, "cert") != NULL) { x5u_flags |= R_FLAG_IGNORE_SERVER_CERTIFICATE; } if (o_strcasestr(optarg, "follow") != NULL) { x5u_flags |= R_FLAG_FOLLOW_REDIRECT; } break; case 'v': // Print version and exit fprintf(stdout, "%s\n", _RNBYC_VERSION_); exit(0); break; case 'h': // Print help and exit print_help(stdout); exit(0); break; case 'd': // Start yder logs debug_mode = 1; break; default: break; } } while (next_option != -1 && !ret); if (debug_mode) { y_init_logs("rnbyc", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting rnbyc debug mode"); } if (!ret) { if (action == R_ACTION_JWKS_OUT) { get_jwks_out(j_arguments, split_keys, x5u_flags, indent, format, out_file, out_file_public); } else if (action == R_ACTION_PARSE_TOKEN) { ret = parse_token(parsed_token, indent, x5u_flags, str_token_public_key, str_token_private_key, password, show_header, show_claims, self_signed); } else if (action == R_ACTION_SERIALIZE_TOKEN) { ret = serialize_token(claims, x5u_flags, str_token_public_key, str_token_private_key, password, alg, enc, enc_alg); } else { ret = EINVAL; fprintf(stderr, "Please epecify an action\n"); print_help(stderr); } } json_decref(j_arguments); o_free(out_file); o_free(out_file_public); o_free(alg); o_free(enc); o_free(enc_alg); o_free(parsed_token); o_free(claims); o_free(str_token_private_key); o_free(str_token_public_key); o_free(password); if (debug_mode) { y_close_logs(); } return ret; }