| 3989 | |
| 3990 | |
| 3991 | dsc* evlRsaVerify(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure) |
| 3992 | { |
| 3993 | tomcryptInitializer(); |
| 3994 | |
| 3995 | fb_assert(args.getCount() == RSA_VERIFY_ARG_MAX || args.getCount() == RSA_VERIFY_ARG_MAX - 1); |
| 3996 | |
| 3997 | Request* request = tdbb->getRequest(); |
| 3998 | |
| 3999 | // parse args and check correctness |
| 4000 | const dsc* dscs[RSA_VERIFY_ARG_MAX]; |
| 4001 | for (unsigned i = 0; i < args.getCount(); ++i) |
| 4002 | dscs[i] = EVL_expr(tdbb, request, args[i]); |
| 4003 | SSHORT pkcs15 = args.getCount() < RSA_VERIFY_ARG_MAX ? 0 : *(SSHORT*)(dscs[RSA_VERIFY_ARG_PKCS_1_5]->dsc_address); |
| 4004 | |
| 4005 | MetaName hashName; |
| 4006 | if (dscs[RSA_VERIFY_ARG_HASH]) |
| 4007 | MOV_get_metaname(tdbb, dscs[RSA_VERIFY_ARG_HASH], hashName); |
| 4008 | if (!hashName.hasData()) |
| 4009 | hashName = "SHA256"; |
| 4010 | string aName(hashName); |
| 4011 | aName.lower(); |
| 4012 | int hash = find_hash(aName.c_str()); |
| 4013 | if (hash < 0) |
| 4014 | status_exception::raise(Arg::Gds(isc_tom_hash_bad) << hashName); |
| 4015 | |
| 4016 | DscValue data(tdbb, dscs[RSA_VERIFY_ARG_VALUE]); |
| 4017 | if (!data.getBytes()) |
| 4018 | return nullptr; |
| 4019 | |
| 4020 | DscValue sign(tdbb, dscs[RSA_VERIFY_ARG_SIGNATURE]); |
| 4021 | if (!sign.getBytes()) |
| 4022 | return boolResult(tdbb, impure, false); |
| 4023 | |
| 4024 | DscValue key(tdbb, dscs[RSA_VERIFY_ARG_KEY], "public key"); |
| 4025 | if (!key.getBytes()) |
| 4026 | return boolResult(tdbb, impure, false); |
| 4027 | rsa_key rsaKey; |
| 4028 | tomCheck(rsa_import(key.getBytes(), key.getLength(), &rsaKey), Arg::Gds(isc_tom_rsa_import)); |
| 4029 | |
| 4030 | SLONG saltLength = 8; |
| 4031 | if (dscHasData(dscs[RSA_VERIFY_ARG_SALTLEN])) |
| 4032 | { |
| 4033 | saltLength = MOV_get_long(tdbb, dscs[RSA_VERIFY_ARG_SALTLEN], 0); |
| 4034 | if (saltLength < 0 || saltLength > getMaxSaltlen(hash, &rsaKey)) |
| 4035 | status_exception::raise(Arg::Gds(isc_arith_except) << Arg::Gds(isc_numeric_out_of_range)); |
| 4036 | } |
| 4037 | |
| 4038 | int state = 0; |
| 4039 | int cryptRc = rsa_verify_hash_ex(sign.getBytes(), sign.getLength(), data.getBytes(), data.getLength(), |
| 4040 | pkcs15 ? LTC_PKCS_1_V1_5 : LTC_PKCS_1_PSS, hash, saltLength, &state, &rsaKey); |
| 4041 | rsa_free(&rsaKey); |
| 4042 | if (cryptRc != CRYPT_INVALID_PACKET) |
| 4043 | tomCheck(cryptRc, Arg::Gds(isc_tom_rsa_verify)); |
| 4044 | else |
| 4045 | state = 0; |
| 4046 | |
| 4047 | return boolResult(tdbb, impure, state); |
| 4048 | } |
nothing calls this directly
no test coverage detected