Example #1
0
static cjose_jwk_t *_cjose_jwk_import_oct(json_t *jwk_json, cjose_err *err)
{
    cjose_jwk_t *jwk = NULL;
    uint8_t *k_buffer = NULL;

    // get the decoded value of k (buflen = 0 means no particular expected len) 
    size_t k_buflen = 0;
    if (!_decode_json_object_base64url_attribute(
            jwk_json, CJOSE_JWK_K_STR, &k_buffer, &k_buflen, err))
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto import_oct_cleanup;
    }

    // create the jwk
    jwk = cjose_jwk_create_oct_spec(k_buffer, k_buflen, err);

    import_oct_cleanup:
    if (NULL != k_buffer)
    {
        cjose_get_dealloc()(k_buffer);
    }

    return jwk;
}
Example #2
0
/*
 * create an "oct" symmetric JWK
 */
oidc_jwk_t *oidc_jwk_create_symmetric_key(apr_pool_t *pool, const char *skid,
		const unsigned char *key, unsigned int key_len, apr_byte_t set_kid, oidc_jose_error_t *err) {

	cjose_err cjose_err;
	cjose_jwk_t *cjose_jwk = cjose_jwk_create_oct_spec(key, key_len,
			&cjose_err);
	if (cjose_jwk == NULL) {
		oidc_jose_error(err, "cjose_jwk_create_oct_spec failed: %s",
				oidc_cjose_e2s(pool, cjose_err));
		return FALSE;
	}

	if (set_kid == TRUE) {
		if (oidc_jwk_set_or_generate_kid(pool, cjose_jwk, skid,
				(const char *) key, key_len, err) == FALSE) {
			cjose_jwk_release(cjose_jwk);
			return FALSE;
		}
	}

	oidc_jwk_t *jwk = oidc_jwk_new(pool);
	jwk->cjose_jwk = cjose_jwk;
	jwk->kid = apr_pstrdup(pool, cjose_jwk_get_kid(jwk->cjose_jwk, &cjose_err));
	jwk->kty = cjose_jwk_get_kty(jwk->cjose_jwk, &cjose_err);
	return jwk;
}
Example #3
0
cjose_jwk_t *cjose_jwk_derive_ecdh_ephemeral_key(
        cjose_jwk_t *jwk_self,
        cjose_jwk_t *jwk_peer,
        cjose_err *err) 
{
    EVP_PKEY_CTX *ctx = NULL;
    EVP_PKEY *pkey_self = NULL;
    EVP_PKEY *pkey_peer = NULL;
    uint8_t *secret = NULL;
    size_t secret_len = 0;
    uint8_t *ephemeral_key = NULL;
    size_t ephemeral_key_len = 0;
    cjose_jwk_t *jwk_ephemeral_key = NULL;

    // get EVP_KEY from jwk_self
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_self, &pkey_self, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // get EVP_KEY from jwk_peer
    if (!_cjose_jwk_evp_key_from_ec_key(jwk_peer, &pkey_peer, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // create derivation context based on local key pair
    ctx = EVP_PKEY_CTX_new(pkey_self, NULL);
    if (NULL == ctx)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // initialize derivation context
    if (1 != EVP_PKEY_derive_init(ctx))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // provide the peer public key
    if (1 != EVP_PKEY_derive_set_peer(ctx, pkey_peer))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // determine buffer length for shared secret
    if(1 != EVP_PKEY_derive(ctx, NULL, &secret_len))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_derive_shared_secret_fail;
    }

    // allocate buffer for shared secret
    secret = (uint8_t *)cjose_get_alloc()(secret_len);
    if (NULL == secret)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;        
    }
    memset(secret, 0, secret_len);

    // derive the shared secret
    if (1 != (EVP_PKEY_derive(ctx, secret, &secret_len)))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _cjose_jwk_derive_shared_secret_fail;                
    }

    // HKDF of the DH shared secret (SHA256, no salt, no info, 256 bit expand)
    ephemeral_key_len = 32;
    ephemeral_key = (uint8_t *)cjose_get_alloc()(ephemeral_key_len);
    if (!cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, 
            secret, secret_len, ephemeral_key, ephemeral_key_len, err))
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // create a JWK of the shared secret
    jwk_ephemeral_key = cjose_jwk_create_oct_spec(
            ephemeral_key, ephemeral_key_len, err);
    if (NULL == jwk_ephemeral_key)
    {
        goto _cjose_jwk_derive_shared_secret_fail;        
    }

    // happy path
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(pkey_self);
    EVP_PKEY_free(pkey_peer);
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);

    return jwk_ephemeral_key;

    // fail path
    _cjose_jwk_derive_shared_secret_fail:
    
    if (NULL != ctx)
    {
        EVP_PKEY_CTX_free(ctx);
    }
    if (NULL != pkey_self)
    {
        EVP_PKEY_free(pkey_self);
    }
    if (NULL != pkey_peer)
    {
        EVP_PKEY_free(pkey_peer);
    }
    if (NULL != jwk_ephemeral_key)
    {
        cjose_jwk_release(jwk_ephemeral_key);
    }
    cjose_get_dealloc()(secret);
    cjose_get_dealloc()(ephemeral_key);
    return NULL;
}