Exemple #1
0
int main(/* int argc, const char *const *argv */) {
    bool valid;
    unsigned char digest[20], sig[68];
    ccec_const_cp_t cp = ccec_cp_256();
    ccec_pub_ctx_decl_cp(cp, key);
    ccec_ctx_init(cp, key);
    return ccec_verify(key, sizeof(digest), digest, sizeof(sig), sig, &valid);
}
static ccec_const_cp_t ccec_cp_for_oid(ccoid_t oid)
{
    if (oid.oid) {
        if (ccoid_equal(oid, ccoid_secp192r1)) {
            return ccec_cp_192();
        } else if (ccoid_equal(oid, ccoid_secp256r1)) {
            return ccec_cp_256();
        } else if (ccoid_equal(oid, ccoid_secp224r1)) {
            return ccec_cp_224();
        } else if (ccoid_equal(oid, ccoid_secp384r1)) {
            return ccec_cp_384();
        } else if (ccoid_equal(oid, ccoid_secp521r1)) {
            return ccec_cp_521();
        }
    }
    return (ccec_const_cp_t){NULL};
}
static OSStatus SecECPrivateKeyInit(SecKeyRef key,
    const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
    ccec_full_ctx_t fullkey;
    fullkey.hdr = key->key;
    OSStatus err = errSecParam;

    switch (encoding) {
    case kSecKeyEncodingPkcs1:
    {
        /* TODO: DER import size (and thus cp), pub.x, pub.y and k. */
        //err = ecc_import(keyData, keyDataLength, fullkey);

        /* DER != PKCS#1, but we'll go along with it */
        ccoid_t oid;
        size_t n;
        ccec_const_cp_t cp;

        require_noerr(ccec_der_import_priv_keytype(keyDataLength, keyData, &oid, &n), abort);
        cp = ccec_cp_for_oid(oid);
        if (cp.zp == NULL) {
            cp = ccec_curve_for_length_lookup(n * 8 /* bytes -> bits */,
                ccec_cp_192(), ccec_cp_224(), ccec_cp_256(), ccec_cp_384(), ccec_cp_521(), NULL);
        }
        require_action(cp.zp != NULL, abort, err = errSecDecode);
        ccec_ctx_init(cp, fullkey);

        require_noerr(ccec_der_import_priv(cp, keyDataLength, keyData, fullkey), abort);
        err = errSecSuccess;
        break;
    }
    case kSecKeyEncodingBytes:
    {
        ccec_const_cp_t cp = getCPForPrivateSize(keyDataLength);
        require(cp.zp != NULL, abort);

        ccec_ctx_init(cp, fullkey);
        size_t pubSize = ccec_export_pub_size(fullkey);

        require(pubSize < (size_t) keyDataLength, abort);
        require_noerr_action(ccec_import_pub(cp, pubSize, keyData, fullkey),
                             abort,
                             err = errSecDecode);


        keyData += pubSize;
        keyDataLength -= pubSize;

        cc_unit *k = ccec_ctx_k(fullkey);
        require_noerr_action(ccn_read_uint(ccec_ctx_n(fullkey), k, keyDataLength, keyData),
                             abort,
                             err = errSecDecode);

        err = errSecSuccess;
        break;

    }
    case kSecGenerateKey:
    {
        CFDictionaryRef parameters = (CFDictionaryRef) keyData;

        CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
        CFIndex keyLengthInBits = getIntValue(ksize);

        ccec_const_cp_t cp = ccec_get_cp(keyLengthInBits);

        if (!cp.zp) {
            secwarning("Invalid or missing key size in: %@", parameters);
            return errSecKeySizeNotAllowed;
        }

        if (!ccec_generate_key(cp, ccrng_seckey, fullkey))
            err = errSecSuccess;
        break;
    }

    default:
        break;
    }
abort:
    return err;
}