Crypto.DSA et al verify messages with various incorrect signatures.
Hi there,
I've started to take a look at the latest master branch of Pike and updated my script to support the newer version of Pike. A few new issues have been found.
Crypto.DSA.State->pkcs_verify
successfully verifies a msg,sig pair with Crypto.SHA256
and Crypto.SHA224
which:
- use long form encoding for the length of
r
and/ors
., - uses a length of sequence
r
and/ors
contains a leading0
.
Here, we see two different string representation of the signature verify as the same (both should be rejected):
int main() {
mapping(string:string) key = ([
"g" : "16a65c58204850704e7502a39757040d34da3a3478c154d4e4a5c02d242ee04f96e61e4bd0904abdac8f37eeb1e09f3182d23c9043cb642f88004160edf9ca09b32076a79c32a627f2473e91879ba2c4e744bd2081544cb55b802c368d1fa83ed489e94e0fa0688e32428a5c78c478c68d0527b71c9a3abb0b0be12c44689639e7d3ce74db101a65aa2b87f64c6826db3ec72f4b5599834bb4edb02f7c90e9a496d3a55d535bebfc45d4f619f63f3dedbb873925c2f224e07731296da887ec1e4748f87efb5fdeb75484316b2232dee553ddaf02112b0d1f02da30973224fe27aeda8b9d4b2922d9ba8be39ed9e103a63c52810bc688b7e2ed4316e1ef17dbde",
"keySize" : 2048,
"p" : "008f7935d9b9aae9bfabed887acf4951b6f32ec59e3baf3718e8eac4961f3efd3606e74351a9c4183339b809e7c2ae1c539ba7475b85d011adb8b47987754984695cac0e8f14b3360828a22ffa27110a3d62a993453409a0fe696c4658f84bdd20819c3709a01057b195adcd00233dba5484b6291f9d648ef883448677979cec04b434a6ac2e75e9985de23db0292fc1118c9ffa9d8181e7338db792b730d7b9e349592f68099872153915ea3d6b8b4653c633458f803b32a4c2e0f27290256e4e3f8a3b0838a1c450e4e18c1a29a37ddf5ea143de4b66ff04903ed5cf1623e158d487c608e97f211cd81dca23cb6e380765f822e342be484c05763939601cd667",
"q" : "00baf696a68578f7dfdee7fa67c977c785ef32b233bae580c0bcd5695d",
"type" : "DsaPublicKey",
"y" : "1e77f842b1ae0fcd9929d394161d41e14614ff7507a9a31f4a1f14d22e2a627a1f4e596624883f1a5b168e9425146f22d5f6ee28757414714bb994ba1129f015d6e04a717edf9b530a5d5cab94f14631e8b4cf79aeb358cc741845553841e8ac461630e804a62f43676ba6794af66899c377b869ea612a7b9fe6611aa96be52eb8b62c979117bbbcca8a7ec1e1ffab1c7dfcfc7048700d3ae3858136e897701d7c2921b5dfef1d1f897f50d96ca1b5c2edc58cada18919e35642f0807eebfa00c99a32f4d095c3188f78ed54711be0325c4b532aeccd6540a567c327225440ea15319bde06510479a1861799e25b57decc73c036d75a0702bd373ca231349931"
]);
string msg;
string sig;
string siq;
msg = "313233343030";
sig = "30813d021d00a545d62d6e336775fb6a9b8495721646a54bd8c6173fc0a2295a1b7b021c3be6bae0e8763818840a9151ad8ed2b3b348e4a2c488d3fbdbbca844"; //use long form encoding for the length of [r, s],
siq = "3082003d021d00a545d62d6e336775fb6a9b8495721646a54bd8c6173fc0a2295a1b7b021c3be6bae0e8763818840a9151ad8ed2b3b348e4a2c488d3fbdbbca844"; //length of sequence [r, s] contains a leading 0
msg = String.hex2string(msg);
sig = String.hex2string(sig);
mixed state = Crypto.DSA.State();
state->set_public_key(Gmp.mpz(key["p"], 16), Gmp.mpz(key["q"], 16), Gmp.mpz(key["g"], 16), Gmp.mpz(key["y"], 16));
bool res = state->pkcs_verify(msg, Crypto.SHA256, sig);
if(res)
write("success!\n");
sig = String.hex2string(siq);
res = state->pkcs_verify(msg, Crypto.SHA256, sig);
if(res)
write("success!\n");
return 0;
}
This seems similar to #10077 (closed), and I'm not sure why I didn't pick it up ealier.
Cheers, Josh
Edited by Henrik (Grubba) Grubbström