Esempio n. 1
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_build_sig_hmac_sha(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    // ensure jwk is OCT
    if (jwk->kty != CJOSE_JWK_KTY_OCT)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // allocate buffer for signature
    jws->sig_len = jws->dig_len;
    jws->sig = (uint8_t *)cjose_get_alloc()(jws->sig_len);
    if (NULL == jws->sig)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }

    memcpy(jws->sig, jws->dig, jws->sig_len);

    // base64url encode signed digest
    if (!cjose_base64url_encode((const uint8_t *)jws->sig, jws->sig_len, &jws->sig_b64u, &jws->sig_b64u_len, err))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;
    }

    return true;
}
Esempio n. 2
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_verify_sig_hmac_sha(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;

    // ensure jwk is OCT
    if (jwk->kty != CJOSE_JWK_KTY_OCT)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jws_verify_sig_hmac_sha_cleanup;
    }

    // verify decrypted digest matches computed digest
    if ((cjose_const_memcmp(jws->dig, jws->sig, jws->dig_len) != 0) || (jws->sig_len != jws->dig_len))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_hmac_sha_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_hmac_sha_cleanup:

    return retval;
}
Esempio n. 3
0
static bool _cjose_jwe_malloc(
        size_t bytes, bool random, 
        uint8_t **buffer,
        cjose_err *err)
{
    *buffer = (uint8_t *)cjose_get_alloc()(bytes);
    if (NULL == *buffer)
    {   
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }   
    if (random)
    {   
        if (RAND_bytes((unsigned char *)*buffer, bytes) != 1)
        {   
            cjose_get_dealloc()(*buffer);
            CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
            return false;
        }   
    }   
    else
    {   
        memset(*buffer, 0, bytes);
    }   
    return true;
}
Esempio n. 4
0
bool _cjose_jwe_import_part(
        cjose_jwe_t *jwe,
        size_t p,
        const char *b64u,
        size_t b64u_len,
        cjose_err *err)
{
    // only the ek and the data parts may be of zero length
    if (b64u_len == 0 && p != 1 && p != 3)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // copy the b64u part to the jwe
    jwe->part[p].b64u = strdup(b64u);
    if (NULL == jwe->part[p].b64u)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }
    jwe->part[p].b64u_len = b64u_len;

    // b64u decode the part
    if (!cjose_base64url_decode(
            jwe->part[p].b64u, jwe->part[p].b64u_len, 
            (uint8_t **)&jwe->part[p].raw, &jwe->part[p].raw_len, err) ||
            NULL == jwe->part[p].raw)
    {
        return false;        
    }

    return true;
}
Esempio n. 5
0
static bool _cjose_jwe_build_hdr(
        cjose_jwe_t *jwe, 
        cjose_header_t *header,
        cjose_err *err)
{
    // save header object as part of the JWE (and incr. refcount)
    jwe->hdr = header;
    json_incref(jwe->hdr);

    // serialize the header
    char *hdr_str = json_dumps(header, JSON_ENCODE_ANY | JSON_PRESERVE_ORDER);
    if (NULL == hdr_str)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }

    // copy the serialized header to JWE (hdr_str is owned by header object)
    jwe->part[0].raw = (uint8_t *)strdup(hdr_str);
    if (NULL == jwe->part[0].raw)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        cjose_get_dealloc()(hdr_str);
        return false;
    }
    jwe->part[0].raw_len = strlen(hdr_str);
    cjose_get_dealloc()(hdr_str);
    
    return true;
}
Esempio n. 6
0
static bool _EC_private_fields(
        const cjose_jwk_t *jwk, json_t *json, cjose_err *err)
{
    ec_keydata      *keydata = (ec_keydata *)jwk->keydata;
    const BIGNUM    *bnD = EC_KEY_get0_private_key(keydata->key);
    uint8_t         *buffer = NULL;
    char            *b64u = NULL;
    size_t          len = 0,
                    offset = 0;
    json_t          *field = NULL;
    bool            result = false;

    // track expected binary data size
    uint8_t     numsize = _ec_size_for_curve(keydata->crv, err);

    // short circuit if 'd' is NULL or 0
    if (!bnD || BN_is_zero(bnD))
    {
        return true;
    }

    buffer = cjose_get_alloc()(numsize);
    if (!buffer)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _ec_to_string_cleanup;
    }

    offset = numsize - BN_num_bytes(bnD);
    memset(buffer, 0, numsize);
    BN_bn2bin(bnD, (buffer + offset));
    if (!cjose_base64url_encode(buffer, numsize, &b64u, &len, err))
    {
        goto _ec_to_string_cleanup;
    }
    field = json_stringn(b64u, len);
    if (!field)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto _ec_to_string_cleanup;
    }
    json_object_set(json, "d", field);
    json_decref(field);
    field = NULL;
    cjose_get_dealloc()(b64u);
    b64u = NULL;

    result = true;

    _ec_to_string_cleanup:
    if (buffer)
    {
        cjose_get_dealloc()(buffer);
    }

    return result;
}
Esempio n. 7
0
File: jwk.c Progetto: tgorol/cjose
cjose_jwk_t *cjose_jwk_create_RSA_spec(
        const cjose_jwk_rsa_keyspec *spec, cjose_err *err)
{
    if (NULL == spec)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    bool        hasPub = (NULL != spec->n && 0 < spec->nlen) &&
                         (NULL != spec->e && 0 < spec->elen);
    bool        hasPriv = (NULL != spec->n && 0 < spec->nlen) &&
                          (NULL != spec->d && 0 < spec->dlen);
    if (!hasPub && !hasPriv)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    RSA     *rsa = NULL;
    rsa = RSA_new();
    if (!rsa)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return NULL;
    }

    if (hasPriv)
    {
        if (!_cjose_jwk_rsa_set(rsa, spec->n, spec->nlen, spec->e, spec->elen, spec->d, spec->dlen))
        {
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
            goto create_RSA_spec_failed;
        }
        _cjose_jwk_rsa_set_factors(rsa, spec->p, spec->plen, spec->q, spec->qlen);
        _cjose_jwk_rsa_set_crt(rsa, spec->dp, spec->dplen, spec->dq, spec->dqlen, spec->qi, spec->qilen);

    }
    else if (hasPub)
    {
        if (!_cjose_jwk_rsa_set(rsa, spec->n, spec->nlen, spec->e, spec->elen, NULL, 0))
        {
            CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
            goto create_RSA_spec_failed;
        }
    }

    return _RSA_new(rsa, err);

    create_RSA_spec_failed:
    if (rsa)
    {
        RSA_free(rsa);
    }

    return NULL;
}
Esempio n. 8
0
static bool _cjose_jwe_validate_hdr(
        cjose_jwe_t *jwe, 
        cjose_header_t *header,
        cjose_err *err)
{
    // make sure we have an alg header
    json_t *alg_obj = json_object_get(header, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // make sure we have an enc header
    json_t *enc_obj = json_object_get(header, CJOSE_HDR_ENC);
    if (NULL == enc_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *enc = json_string_value(enc_obj);

    // set JWE build functions based on header contents
    if (strcmp(alg, CJOSE_HDR_ALG_RSA_OAEP) == 0)
    {
        jwe->fns.encrypt_ek = _cjose_jwe_encrypt_ek_rsa_oaep;
        jwe->fns.decrypt_ek = _cjose_jwe_decrypt_ek_rsa_oaep;
    }
    if (strcmp(alg, CJOSE_HDR_ALG_DIR) == 0)
    {
        jwe->fns.encrypt_ek = _cjose_jwe_encrypt_ek_dir;
        jwe->fns.decrypt_ek = _cjose_jwe_decrypt_ek_dir;
    }
    if (strcmp(enc, CJOSE_HDR_ENC_A256GCM) == 0)
    {
        jwe->fns.set_cek = _cjose_jwe_set_cek_a256gcm;
        jwe->fns.set_iv = _cjose_jwe_set_iv_a256gcm;
        jwe->fns.encrypt_dat = _cjose_jwe_encrypt_dat_a256gcm;
        jwe->fns.decrypt_dat = _cjose_jwe_decrypt_dat_a256gcm;
    }

    // ensure required builders have been assigned
    if (NULL == jwe->fns.set_cek ||
        NULL == jwe->fns.encrypt_ek ||
        NULL == jwe->fns.decrypt_ek ||
        NULL == jwe->fns.set_iv ||
        NULL == jwe->fns.encrypt_dat ||
        NULL == jwe->fns.decrypt_dat)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    return true;
}
Esempio n. 9
0
static inline bool _RSA_json_field(
        BIGNUM *param, const char *name, json_t *json, cjose_err *err)
{
    json_t      *field = NULL;
    uint8_t     *data = NULL;
    char        *b64u = NULL;
    size_t      datalen = 0,
                b64ulen = 0;
    bool        result = false;

    if (!param)
    {
        return true;
    }

    datalen = BN_num_bytes(param);
    data = cjose_get_alloc()(sizeof(uint8_t) * datalen);
    if (!data)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto RSA_json_field_cleanup;
    }
    BN_bn2bin(param, data);
    if (!cjose_base64url_encode(data, datalen, &b64u, &b64ulen, err))
    {
        goto RSA_json_field_cleanup;
    }
    field = json_stringn(b64u, b64ulen);
    if (!field)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto RSA_json_field_cleanup;
    }
    json_object_set(json, name, field);
    json_decref(field);
    field = NULL;
    result = true;

    RSA_json_field_cleanup:
    if (b64u)
    {
        cjose_get_dealloc()(b64u);
        b64u = NULL;
    }
    if (data)
    {
        cjose_get_dealloc()(data);
        data = NULL;
    }

    return result;
}
Esempio n. 10
0
File: jwk.c Progetto: tgorol/cjose
cjose_jwk_t *cjose_jwk_create_RSA_random(
        size_t keysize, const uint8_t *e, size_t elen, cjose_err *err)
{
    if (0 == keysize)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }
    if (NULL == e || 0 >= elen)
    {
        e = DEFAULT_E_DAT;
        elen = DEFAULT_E_LEN;
    }

    RSA     *rsa = NULL;
    BIGNUM  *bn = NULL;

    rsa = RSA_new();
    if (!rsa)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_RSA_random_failed;
    }

    bn = BN_bin2bn(e, elen, NULL);
    if (!bn)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_RSA_random_failed;
    }

    if (0 == RSA_generate_key_ex(rsa, keysize, bn, NULL))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_RSA_random_failed;
    }

    BN_free(bn);
    return _RSA_new(rsa, err);

    create_RSA_random_failed:
    if (bn)
    {
        BN_free(bn);
    }
    if (rsa)
    {
        RSA_free(rsa);
    }
    return NULL;
}
Esempio n. 11
0
static bool _cjose_jwe_encrypt_ek_rsa_oaep(
        cjose_jwe_t *jwe, 
        const cjose_jwk_t *jwk,
        cjose_err *err)
{
    // jwk must be RSA and have the necessary public parts set
    if (jwk->kty != CJOSE_JWK_KTY_RSA ||
        NULL == jwk->keydata ||
        NULL == ((RSA *)jwk->keydata)->e || 
        NULL == ((RSA *)jwk->keydata)->n)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // generate random cek
    if (!jwe->fns.set_cek(jwe, NULL, err))
    {
        return false;
    }   

    // the size of the ek will match the size of the RSA key
    jwe->part[1].raw_len = RSA_size((RSA *)jwk->keydata);

    // for OAEP padding - the RSA size - 41 must be greater than input
    if (jwe->cek_len >= jwe->part[1].raw_len - 41)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;        
    }

    // allocate memory for RSA encryption
    cjose_get_dealloc()(jwe->part[1].raw);
    if (!_cjose_jwe_malloc(jwe->part[1].raw_len, false, &jwe->part[1].raw, err))
    {
        return false;        
    }

    // encrypt the CEK using RSAES-OAEP
    if (RSA_public_encrypt(jwe->cek_len, jwe->cek, jwe->part[1].raw,
            (RSA *)jwk->keydata, RSA_PKCS1_OAEP_PADDING) != 
            jwe->part[1].raw_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;        
    }

    return true;
}
Esempio n. 12
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_build_cser(cjose_jws_t *jws, cjose_err *err)
{
    // both sign and import should be setting these - but check just in case
    if (NULL == jws->hdr_b64u || NULL == jws->dat_b64u || NULL == jws->sig_b64u)
    {
        return false;
    }

    // compute length of compact serialization
    jws->cser_len = jws->hdr_b64u_len + jws->dat_b64u_len + jws->sig_b64u_len + 3;

    // allocate buffer for compact serialization
    assert(NULL == jws->cser);
    jws->cser = (char *)cjose_get_alloc()(jws->cser_len);
    if (NULL == jws->cser)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        return false;
    }

    // build the compact serialization
    snprintf(jws->cser, jws->cser_len, "%s.%s.%s", jws->hdr_b64u, jws->dat_b64u, jws->sig_b64u);

    return true;
}
Esempio n. 13
0
File: jws.c Progetto: cisco/cjose
bool cjose_jws_verify(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    if (NULL == jws || NULL == jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // validate JWS header
    if (!_cjose_jws_validate_hdr(jws, err))
    {
        return false;
    }

    // build JWS digest from header and payload (hashed signing input value)
    if (!jws->fns.digest(jws, jwk, err))
    {
        return false;
    }

    // verify JWS signature
    if (!jws->fns.verify(jws, jwk, err))
    {
        return false;
    }

    return true;
}
Esempio n. 14
0
uint8_t *cjose_jwe_decrypt(
        cjose_jwe_t *jwe,
        const cjose_jwk_t *jwk,
        size_t *content_len,
        cjose_err *err)
{
    if (NULL == jwe || NULL == jwk || NULL == content_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

     // decrypt JWE content-encryption key from encrypted key
    if (!jwe->fns.decrypt_ek(jwe, jwk, err))
    {
        return NULL;
    }

    // decrypt JWE encrypted data
    if (!jwe->fns.decrypt_dat(jwe, err))
    {
        return NULL;
    }

    // take the plaintext data from the jwe object
    uint8_t *content = jwe->dat;
    *content_len = jwe->dat_len;
    jwe->dat = NULL;
    jwe->dat_len = 0;

    return content;
}
Esempio n. 15
0
bool cjose_jwk_hkdf(
        const EVP_MD *md,
        const uint8_t *salt,
        size_t salt_len,
        const uint8_t *info,
        size_t info_len,
        const uint8_t *ikm, 
        size_t ikm_len, 
        uint8_t *okm,
        unsigned int okm_len,
        cjose_err *err)
{
    // current impl. is very limited: SHA256, 256 bit output, and no info
    if ((EVP_sha256() != md) || (0 != info_len) || (32 != okm_len)) {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // HKDF-Extract, HMAC-SHA256(salt, IKM) -> PRK
    unsigned int prk_len;
    unsigned char prk[EVP_MAX_MD_SIZE];
    HMAC(md, salt, salt_len, ikm, ikm_len, prk, &prk_len);
 
    // HKDF-Expand, HMAC-SHA256(PRK,0x01) -> OKM
    const unsigned char t[] = { 0x01 };
    HMAC(md, prk, prk_len, t, sizeof(t), okm, NULL);

    return true;
}
Esempio n. 16
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;
}
Esempio n. 17
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_validate_hdr(cjose_jws_t *jws, cjose_err *err)
{
    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if ((NULL == alg_obj) || (!json_is_string(alg_obj)))
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    if ((strcmp(alg, CJOSE_HDR_ALG_PS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_PS384) == 0)
        || (strcmp(alg, CJOSE_HDR_ALG_PS512) == 0))
    {
        jws->fns.digest = _cjose_jws_build_dig_sha;
        jws->fns.sign = _cjose_jws_build_sig_ps;
        jws->fns.verify = _cjose_jws_verify_sig_ps;
    }
    else if ((strcmp(alg, CJOSE_HDR_ALG_RS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_RS384) == 0)
             || (strcmp(alg, CJOSE_HDR_ALG_RS512) == 0))
    {
        jws->fns.digest = _cjose_jws_build_dig_sha;
        jws->fns.sign = _cjose_jws_build_sig_rs;
        jws->fns.verify = _cjose_jws_verify_sig_rs;
    }
    else if ((strcmp(alg, CJOSE_HDR_ALG_HS256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_HS384) == 0)
             || (strcmp(alg, CJOSE_HDR_ALG_HS512) == 0))
    {
        jws->fns.digest = _cjose_jws_build_dig_hmac_sha;
        jws->fns.sign = _cjose_jws_build_sig_hmac_sha;
        jws->fns.verify = _cjose_jws_verify_sig_hmac_sha;
    }
    else if ((strcmp(alg, CJOSE_HDR_ALG_ES256) == 0) || (strcmp(alg, CJOSE_HDR_ALG_ES384) == 0)
             || (strcmp(alg, CJOSE_HDR_ALG_ES512) == 0))
    {
        jws->fns.digest = _cjose_jws_build_dig_sha;
        jws->fns.sign = _cjose_jws_build_sig_ec;
        jws->fns.verify = _cjose_jws_verify_sig_ec;
    }
    else
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    return true;
}
Esempio n. 18
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_verify_sig_rs(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;

    // ensure jwk is RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jws_verify_sig_rs_cleanup;
    }

    // make sure we have an alg header
    json_t *alg_obj = json_object_get(jws->hdr, CJOSE_HDR_ALG);
    if (NULL == alg_obj)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }
    const char *alg = json_string_value(alg_obj);

    // build digest using SHA-256/384/512 digest algorithm
    int digest_alg = -1;
    if (strcmp(alg, CJOSE_HDR_ALG_RS256) == 0)
        digest_alg = NID_sha256;
    else if (strcmp(alg, CJOSE_HDR_ALG_RS384) == 0)
        digest_alg = NID_sha384;
    else if (strcmp(alg, CJOSE_HDR_ALG_RS512) == 0)
        digest_alg = NID_sha512;
    if (-1 == digest_alg)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_rs_cleanup;
    }

    if (RSA_verify(digest_alg, jws->dig, jws->dig_len, jws->sig, jws->sig_len, (RSA *)jwk->keydata) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_rs_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_rs_cleanup:

    return retval;
}
Esempio n. 19
0
size_t cjose_jwk_get_keysize(const cjose_jwk_t *jwk, cjose_err *err)
{
    if (!jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return 0;
    }
    return jwk->keysize;
}
Esempio n. 20
0
void *cjose_jwk_get_keydata(const cjose_jwk_t *jwk, cjose_err *err)
{
    if (!jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }
    return jwk->keydata;
}
Esempio n. 21
0
const char * cjose_jwk_name_for_kty(cjose_jwk_kty_t kty, cjose_err *err)
{
    if (0 == kty || CJOSE_JWK_KTY_OCT < kty)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    return JWK_KTY_NAMES[kty - CJOSE_JWK_KTY_RSA];
}
Esempio n. 22
0
const char *cjose_jwk_get_kid(const cjose_jwk_t *jwk, cjose_err *err)
{
    if (!jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    return jwk->kid;
}
Esempio n. 23
0
cjose_jwk_kty_t cjose_jwk_get_kty(const cjose_jwk_t *jwk, cjose_err *err)
{
    if (!jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return -1;
    }

    return jwk->kty;
}
Esempio n. 24
0
File: jws.c Progetto: cisco/cjose
static bool _cjose_jws_verify_sig_ec(cjose_jws_t *jws, const cjose_jwk_t *jwk, cjose_err *err)
{
    bool retval = false;

    // ensure jwk is EC
    if (jwk->kty != CJOSE_JWK_KTY_EC)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    ec_keydata *keydata = (ec_keydata *)jwk->keydata;
    EC_KEY *ec = keydata->key;

    ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
    int key_len = jws->sig_len / 2;

#if defined(CJOSE_OPENSSL_11X)
    BIGNUM *pr = BN_new(), *ps = BN_new();
    BN_bin2bn(jws->sig, key_len, pr);
    BN_bin2bn(jws->sig + key_len, key_len, ps);
    ECDSA_SIG_set0(ecdsa_sig, pr, ps);
#else
    BN_bin2bn(jws->sig, key_len, ecdsa_sig->r);
    BN_bin2bn(jws->sig + key_len, key_len, ecdsa_sig->s);
#endif

    if (ECDSA_do_verify(jws->dig, jws->dig_len, ecdsa_sig, ec) != 1)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jws_verify_sig_ec_cleanup;
    }

    // if we got this far - success
    retval = true;

_cjose_jws_verify_sig_ec_cleanup:
    if (ecdsa_sig)
        ECDSA_SIG_free(ecdsa_sig);

    return retval;
}
Esempio n. 25
0
static bool _cjose_jwk_evp_key_from_ec_key(
        cjose_jwk_t *jwk, EVP_PKEY **key, cjose_err *err)
{
    // validate that the jwk is of type EC and we have a valid out-param
    if (NULL == jwk || 
            CJOSE_JWK_KTY_EC != jwk->kty || 
            NULL == jwk->keydata ||
            NULL == key ||
            NULL != *key)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto _cjose_jwk_evp_key_from_ec_key_fail;        
    }

    // create a blank EVP_PKEY
    *key = EVP_PKEY_new();
    if (NULL == key)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_evp_key_from_ec_key_fail;
    }

    // assign the EVP_PKEY to reference the jwk's internal EC_KEY structure
    if (1 != EVP_PKEY_set1_EC_KEY(
            *key, ((struct _ec_keydata_int *)(jwk->keydata))->key))
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        goto _cjose_jwk_evp_key_from_ec_key_fail;
    }

    // happy path
    return true;

    // fail path
    _cjose_jwk_evp_key_from_ec_key_fail:

    EVP_PKEY_free(*key);
    *key = NULL;

    return false;
}
Esempio n. 26
0
cjose_jwk_t *cjose_jwk_create_oct_random(size_t keysize, cjose_err *err)
{
    cjose_jwk_t *           jwk = NULL;
    uint8_t *               buffer = NULL;

    if (0 == keysize)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto create_oct_failed;
    }

    // resize to bytes
    size_t buffersize = sizeof(uint8_t) * (keysize / 8);

    buffer = (uint8_t *)cjose_get_alloc()(buffersize);
    if (NULL == buffer)
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_oct_failed;
    }
    if (1 != RAND_bytes(buffer, buffersize))
    {
        goto create_oct_failed;
    }

    jwk = _oct_new(buffer, keysize, err);
    if (NULL == jwk)
    {
        goto create_oct_failed;
    }
    return jwk;

    create_oct_failed:
    if (buffer)
    {
        cjose_get_dealloc()(buffer);
        buffer = NULL;
    }

    return NULL;
}
Esempio n. 27
0
cjose_jwk_t *cjose_jwk_create_EC_random(cjose_jwk_ec_curve crv, cjose_err *err)
{
    cjose_jwk_t *   jwk = NULL;
    EC_KEY *        ec = NULL;

    ec = EC_KEY_new_by_curve_name(crv);
    if (!ec)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        goto create_EC_failed;
    }
    
    if (1 != EC_KEY_generate_key(ec))
    {
        CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
        goto create_EC_failed;
    }

    jwk = _EC_new(crv, ec, err);
    if (!jwk)
    {
        goto create_EC_failed;
    }

    return jwk;

    create_EC_failed:
    if (jwk)
    {
        cjose_get_dealloc()(jwk);
        jwk = NULL;
    }
    if (ec)
    {
        EC_KEY_free(ec);
        ec = NULL;
    }

    return NULL;
}
Esempio n. 28
0
File: jws.c Progetto: cisco/cjose
bool cjose_jws_get_plaintext(const cjose_jws_t *jws, uint8_t **plaintext, size_t *plaintext_len, cjose_err *err)
{
    if (NULL == jws || NULL == plaintext || NULL == jws->dat)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    *plaintext = jws->dat;
    *plaintext_len = jws->dat_len;

    return true;
}
Esempio n. 29
0
cjose_jwk_t * cjose_jwk_retain(cjose_jwk_t *jwk, cjose_err *err)
{
    if (!jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return NULL;
    }

    ++(jwk->retained);
    // TODO: check for overflow

    return jwk;
}
Esempio n. 30
0
static bool _cjose_jwe_decrypt_ek_rsa_oaep(
        cjose_jwe_t *jwe, 
        const cjose_jwk_t *jwk,
        cjose_err *err)
{
    if (NULL == jwe || NULL == jwk)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;
    }

    // jwk must be RSA
    if (jwk->kty != CJOSE_JWK_KTY_RSA)
    {
        CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
        return false;        
    }

    // we don't know the size of the key to expect, but must be < RSA_size
    cjose_get_dealloc()(jwe->cek);
    size_t buflen = RSA_size((RSA *)jwk->keydata);
    if (!_cjose_jwe_malloc(buflen, false, &jwe->cek, err))
    {
        return false;
    }

    // decrypt the CEK using RSAES-OAEP
    jwe->cek_len = RSA_private_decrypt(
            jwe->part[1].raw_len, jwe->part[1].raw, jwe->cek, 
            (RSA *)jwk->keydata, RSA_PKCS1_OAEP_PADDING);
    if (-1 == jwe->cek_len)
    {
        CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
        return false;
    }

    return true;
}