diff --git a/openpgpsdk/src/openpgpsdk/signature.c b/openpgpsdk/src/openpgpsdk/signature.c index 85103844d..d44e2d811 100644 --- a/openpgpsdk/src/openpgpsdk/signature.c +++ b/openpgpsdk/src/openpgpsdk/signature.c @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -206,77 +205,105 @@ ops_boolean_t encode_hash_buf(const unsigned char *M, size_t mLen, // XXX: both this and verify would be clearer if the signature were // treated as an MPI. -static void rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa, +static ops_boolean_t rsa_sign(ops_hash_t *hash, const ops_rsa_public_key_t *rsa, const ops_rsa_secret_key_t *srsa, ops_create_info_t *opt) - { - unsigned char hashbuf[8192]; - unsigned char sigbuf[8192]; - unsigned keysize; - unsigned hashsize; - unsigned n; - unsigned t; - BIGNUM *bn; +{ + unsigned char hashbuf[8192]; + unsigned char sigbuf[8192]; + unsigned keysize; + unsigned hashsize; + unsigned n; + unsigned t; + BIGNUM *bn; - // XXX: we assume hash is sha-1 for now - hashsize=20+sizeof prefix_sha1; + // XXX: we assume hash is sha-1 for now + hashsize=20+sizeof prefix_sha1; - keysize=BN_num_bytes(rsa->n); - assert(keysize <= sizeof hashbuf); - assert(10+hashsize <= keysize); + keysize=BN_num_bytes(rsa->n); - hashbuf[0]=0; - hashbuf[1]=1; - if (debug) - printf("rsa_sign: PS is %d\n", keysize-hashsize-1-2); - for(n=2 ; n < keysize-hashsize-1 ; ++n) - hashbuf[n]=0xff; - hashbuf[n++]=0; + if(keysize > sizeof hashbuf) + { + fprintf(stderr,"Keysize too large. limit is %lu, size was %u",sizeof(hashbuf), keysize) ; + return ops_false ; + } + if(10+hashsize > keysize) + { + fprintf(stderr,"10+hashsize > keysize. Can't sign!") ; + return ops_false ; + } - memcpy(&hashbuf[n], prefix_sha1, sizeof prefix_sha1); - n+=sizeof prefix_sha1; + hashbuf[0]=0; + hashbuf[1]=1; + if (debug) + printf("rsa_sign: PS is %d\n", keysize-hashsize-1-2); + for(n=2 ; n < keysize-hashsize-1 ; ++n) + hashbuf[n]=0xff; + hashbuf[n++]=0; - t=hash->finish(hash, &hashbuf[n]); - assert(t == 20); + memcpy(&hashbuf[n], prefix_sha1, sizeof prefix_sha1); + n+=sizeof prefix_sha1; - ops_write(&hashbuf[n], 2, opt); + t=hash->finish(hash, &hashbuf[n]); - n+=t; - assert(n == keysize); + if(t != 20) + { + fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ; + return ops_false ; + } - t=ops_rsa_private_encrypt(sigbuf, hashbuf, keysize, srsa, rsa); - bn=BN_bin2bn(sigbuf, t, NULL); - ops_write_mpi(bn, opt); - BN_free(bn); - } + ops_write(&hashbuf[n], 2, opt); -static void dsa_sign(ops_hash_t *hash, const ops_dsa_public_key_t *dsa, + n+=t; + + if(n != keysize) + { + fprintf(stderr,"Size error in hashed data. can't sign.") ; + return ops_false ; + } + + t=ops_rsa_private_encrypt(sigbuf, hashbuf, keysize, srsa, rsa); + bn=BN_bin2bn(sigbuf, t, NULL); + ops_write_mpi(bn, opt); + BN_free(bn); + + return ops_true ; +} + +static ops_boolean_t dsa_sign(ops_hash_t *hash, const ops_dsa_public_key_t *dsa, const ops_dsa_secret_key_t *sdsa, ops_create_info_t *cinfo) - { - unsigned char hashbuf[8192]; - unsigned hashsize; - unsigned t; +{ + unsigned char hashbuf[8192]; + unsigned hashsize; + unsigned t; - // hashsize must be "equal in size to the number of bits of q, - // the group generated by the DSA key's generator value - // 160/8 = 20 + // hashsize must be "equal in size to the number of bits of q, + // the group generated by the DSA key's generator value + // 160/8 = 20 - hashsize=20; + hashsize=20; - // finalise hash - t=hash->finish(hash, &hashbuf[0]); - assert(t == 20); + // finalise hash + t=hash->finish(hash, &hashbuf[0]); - ops_write(&hashbuf[0], 2, cinfo); + if(t != 20) + { + fprintf(stderr,"Wrong hash size. Should be 20! can't sign.") ; + return ops_false ; + } - // write signature to buf - DSA_SIG* dsasig; - dsasig=ops_dsa_sign(hashbuf, hashsize, sdsa, dsa); + ops_write(&hashbuf[0], 2, cinfo); - // convert and write the sig out to memory - ops_write_mpi(dsasig->r, cinfo); - ops_write_mpi(dsasig->s, cinfo); - DSA_SIG_free(dsasig); - } + // write signature to buf + DSA_SIG* dsasig; + dsasig=ops_dsa_sign(hashbuf, hashsize, sdsa, dsa); + + // convert and write the sig out to memory + ops_write_mpi(dsasig->r, cinfo); + ops_write_mpi(dsasig->s, cinfo); + DSA_SIG_free(dsasig); + + return ops_true ; +} static ops_boolean_t rsa_verify(ops_hash_algorithm_t type, const unsigned char *hash, size_t hash_length, @@ -292,12 +319,20 @@ static ops_boolean_t rsa_verify(ops_hash_algorithm_t type, keysize=BN_num_bytes(rsa->n); /* RSA key can't be bigger than 65535 bits, so... */ - assert(keysize <= sizeof hashbuf_from_sig); - assert((unsigned)BN_num_bits(sig->sig) <= 8*sizeof sigbuf); + + if(keysize > sizeof hashbuf_from_sig) + { + fprintf(stderr,"Can't verify signature: keysize too big.") ; + return ops_false ; + } + if((unsigned)BN_num_bits(sig->sig) > 8*sizeof sigbuf) + { + fprintf(stderr,"Can't verify signature: signature too big.") ; + return ops_false ; + } BN_bn2bin(sig->sig, sigbuf); - n=ops_rsa_public_decrypt(hashbuf_from_sig, sigbuf, BN_num_bytes(sig->sig), - rsa); + n=ops_rsa_public_decrypt(hashbuf_from_sig, sigbuf, BN_num_bytes(sig->sig), rsa); int debug_len_decrypted=n; if(n != keysize) // obviously, this includes error returns @@ -809,7 +844,6 @@ ops_boolean_t ops_write_signature(ops_create_signature_t *sig, default: fprintf(stderr, "Unsupported algorithm %d when signing. Sorry.\n", skey->public_key.algorithm); return ops_false ; - //assert(0); } if(sig->hashed_data_length == (unsigned)-1) @@ -847,11 +881,19 @@ ops_boolean_t ops_write_signature(ops_create_signature_t *sig, case OPS_PKA_RSA: case OPS_PKA_RSA_ENCRYPT_ONLY: case OPS_PKA_RSA_SIGN_ONLY: - rsa_sign(&sig->hash, &key->key.rsa, &skey->key.rsa, sig->info); + if(!rsa_sign(&sig->hash, &key->key.rsa, &skey->key.rsa, sig->info)) + { + fprintf(stderr, "error in rsa_sign. Can't produce signature\n") ; + return ops_false; + } break; case OPS_PKA_DSA: - dsa_sign(&sig->hash, &key->key.dsa, &skey->key.dsa, sig->info); + if(!dsa_sign(&sig->hash, &key->key.dsa, &skey->key.dsa, sig->info)) + { + fprintf(stderr, "error in dsa_sign. Can't produce signature\n") ; + return ops_false; + } break; default: @@ -1051,7 +1093,6 @@ ops_boolean_t ops_sign_file_as_cleartext(const char* input_filename, close(fd_in) ; ops_teardown_file_write(cinfo, fd_out); return ops_false ; - //assert(n>=0); } ops_write(buf, n, cinfo); }