version 1.6.4.2, 2001/03/21 18:53:09 |
version 1.7, 2001/06/06 23:13:54 |
|
|
u_char **sigp, int *lenp, |
u_char **sigp, int *lenp, |
u_char *data, int datalen) |
u_char *data, int datalen) |
{ |
{ |
u_char *digest; |
|
u_char *ret; |
|
DSA_SIG *sig; |
DSA_SIG *sig; |
EVP_MD *evp_md = EVP_sha1(); |
EVP_MD *evp_md = EVP_sha1(); |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
u_int rlen; |
u_char *digest, *ret, sigblob[SIGBLOB_LEN]; |
u_int slen; |
u_int rlen, slen, len, dlen; |
u_int len, dlen; |
|
u_char sigblob[SIGBLOB_LEN]; |
|
Buffer b; |
Buffer b; |
|
|
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
|
|
EVP_DigestFinal(&md, digest, NULL); |
EVP_DigestFinal(&md, digest, NULL); |
|
|
sig = DSA_do_sign(digest, dlen, key->dsa); |
sig = DSA_do_sign(digest, dlen, key->dsa); |
if (sig == NULL) { |
|
fatal("ssh_dss_sign: cannot sign"); |
|
} |
|
memset(digest, 0, dlen); |
memset(digest, 0, dlen); |
xfree(digest); |
xfree(digest); |
|
if (sig == NULL) { |
|
error("ssh_dss_sign: sign failed"); |
|
return -1; |
|
} |
|
|
rlen = BN_num_bytes(sig->r); |
rlen = BN_num_bytes(sig->r); |
slen = BN_num_bytes(sig->s); |
slen = BN_num_bytes(sig->s); |
|
|
DSA_SIG_free(sig); |
DSA_SIG_free(sig); |
return -1; |
return -1; |
} |
} |
debug("sig size %d %d", rlen, slen); |
|
|
|
memset(sigblob, 0, SIGBLOB_LEN); |
memset(sigblob, 0, SIGBLOB_LEN); |
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); |
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); |
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); |
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen); |
DSA_SIG_free(sig); |
DSA_SIG_free(sig); |
|
|
if (datafellows & SSH_BUG_SIGBLOB) { |
if (datafellows & SSH_BUG_SIGBLOB) { |
debug("datafellows"); |
|
ret = xmalloc(SIGBLOB_LEN); |
ret = xmalloc(SIGBLOB_LEN); |
memcpy(ret, sigblob, SIGBLOB_LEN); |
memcpy(ret, sigblob, SIGBLOB_LEN); |
if (lenp != NULL) |
if (lenp != NULL) |
|
|
u_char *signature, int signaturelen, |
u_char *signature, int signaturelen, |
u_char *data, int datalen) |
u_char *data, int datalen) |
{ |
{ |
Buffer b; |
|
u_char *digest; |
|
DSA_SIG *sig; |
DSA_SIG *sig; |
EVP_MD *evp_md = EVP_sha1(); |
EVP_MD *evp_md = EVP_sha1(); |
EVP_MD_CTX md; |
EVP_MD_CTX md; |
u_char *sigblob; |
u_char *digest, *sigblob; |
char *txt; |
|
u_int len, dlen; |
u_int len, dlen; |
int rlen; |
int rlen, ret; |
int ret; |
Buffer b; |
|
|
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
error("ssh_dss_verify: no DSA key"); |
error("ssh_dss_verify: no DSA key"); |
return -1; |
return -1; |
} |
} |
|
|
if (!(datafellows & SSH_BUG_SIGBLOB) && |
|
signaturelen == SIGBLOB_LEN) { |
|
datafellows |= ~SSH_BUG_SIGBLOB; |
|
log("autodetect SSH_BUG_SIGBLOB"); |
|
} else if ((datafellows & SSH_BUG_SIGBLOB) && |
|
signaturelen != SIGBLOB_LEN) { |
|
log("autoremove SSH_BUG_SIGBLOB"); |
|
datafellows &= ~SSH_BUG_SIGBLOB; |
|
} |
|
|
|
debug("len %d datafellows %d", signaturelen, datafellows); |
|
|
|
/* fetch signature */ |
/* fetch signature */ |
if (datafellows & SSH_BUG_SIGBLOB) { |
if (datafellows & SSH_BUG_SIGBLOB) { |
sigblob = signature; |
sigblob = signature; |
|
|
xfree(digest); |
xfree(digest); |
DSA_SIG_free(sig); |
DSA_SIG_free(sig); |
|
|
switch (ret) { |
debug("ssh_dss_verify: signature %s", |
case 1: |
ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error"); |
txt = "correct"; |
|
break; |
|
case 0: |
|
txt = "incorrect"; |
|
break; |
|
case -1: |
|
default: |
|
txt = "error"; |
|
break; |
|
} |
|
debug("ssh_dss_verify: signature %s", txt); |
|
return ret; |
return ret; |
} |
} |