| 3920 | |
| 3921 | |
| 3922 | dsc* evlRsaSign(thread_db* tdbb, const SysFunction* function, const NestValueArray& args, impure_value* impure) |
| 3923 | { |
| 3924 | tomcryptInitializer(); |
| 3925 | |
| 3926 | fb_assert(args.getCount() == RSA_SIGN_ARG_MAX || args.getCount() == RSA_SIGN_ARG_MAX - 1); |
| 3927 | |
| 3928 | Request* request = tdbb->getRequest(); |
| 3929 | |
| 3930 | // parse args and check correctness |
| 3931 | const dsc* dscs[RSA_SIGN_ARG_MAX]; |
| 3932 | for (unsigned i = 0; i < args.getCount(); ++i) |
| 3933 | dscs[i] = EVL_expr(tdbb, request, args[i]); |
| 3934 | |
| 3935 | SSHORT pkcs15 = args.getCount() < RSA_SIGN_ARG_MAX ? 0 : *(SSHORT*)(dscs[RSA_SIGN_ARG_PKCS_1_5]->dsc_address); |
| 3936 | |
| 3937 | MetaName hashName; |
| 3938 | if (dscs[RSA_SIGN_ARG_HASH]) |
| 3939 | MOV_get_metaname(tdbb, dscs[RSA_SIGN_ARG_HASH], hashName); |
| 3940 | if (!hashName.hasData()) |
| 3941 | hashName = "SHA256"; |
| 3942 | string aName(hashName); |
| 3943 | aName.lower(); |
| 3944 | int hash = find_hash(aName.c_str()); |
| 3945 | if (hash < 0) |
| 3946 | status_exception::raise(Arg::Gds(isc_tom_hash_bad) << hashName); |
| 3947 | |
| 3948 | DscValue data(tdbb, dscs[RSA_SIGN_ARG_VALUE]); |
| 3949 | if (!data.getBytes()) |
| 3950 | return nullptr; |
| 3951 | |
| 3952 | DscValue key(tdbb, dscs[RSA_SIGN_ARG_KEY], "private key"); |
| 3953 | if (!key.getBytes()) |
| 3954 | return nullptr; |
| 3955 | rsa_key rsaKey; |
| 3956 | tomCheck(rsa_import(key.getBytes(), key.getLength(), &rsaKey), Arg::Gds(isc_tom_rsa_import)); |
| 3957 | |
| 3958 | SLONG saltLength = 8; |
| 3959 | if (dscHasData(dscs[RSA_SIGN_ARG_SALTLEN])) |
| 3960 | { |
| 3961 | saltLength = MOV_get_long(tdbb, dscs[RSA_SIGN_ARG_SALTLEN], 0); |
| 3962 | if (saltLength < 0 || saltLength > getMaxSaltlen(hash, &rsaKey)) |
| 3963 | status_exception::raise(Arg::Gds(isc_arith_except) << Arg::Gds(isc_numeric_out_of_range)); |
| 3964 | } |
| 3965 | |
| 3966 | unsigned long signLen = 1024; |
| 3967 | UCharBuffer sign; |
| 3968 | int cryptRc = rsa_sign_hash_ex(data.getBytes(), data.getLength(), sign.getBuffer(signLen), &signLen, |
| 3969 | pkcs15 ? LTC_PKCS_1_V1_5 : LTC_PKCS_1_PSS, prng().getState(), prng().getIndex(), hash, saltLength, &rsaKey); |
| 3970 | rsa_free(&rsaKey); |
| 3971 | tomCheck(cryptRc, Arg::Gds(isc_tom_rsa_sign)); |
| 3972 | |
| 3973 | dsc result; |
| 3974 | result.makeText(signLen, ttype_binary, sign.begin()); |
| 3975 | EVL_make_value(tdbb, &result, impure); |
| 3976 | return &impure->vlu_desc; |
| 3977 | } |
| 3978 | |
| 3979 |
nothing calls this directly
no test coverage detected