[BACK]Return to ssh-dss.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/ssh-dss.c between version 1.6 and 1.6.6.3

version 1.6, 2001/02/08 19:30:52 version 1.6.6.3, 2002/03/09 00:20:45
Line 42 
Line 42 
 int  int
 ssh_dss_sign(  ssh_dss_sign(
     Key *key,      Key *key,
     u_char **sigp, int *lenp,      u_char **sigp, u_int *lenp,
     u_char *data, int datalen)      u_char *data, u_int datalen)
 {  {
         u_char *digest;  
         u_char *ret;  
         DSA_SIG *sig;          DSA_SIG *sig;
         EVP_MD *evp_md = EVP_sha1();          const EVP_MD *evp_md = EVP_sha1();
         EVP_MD_CTX md;          EVP_MD_CTX md;
         u_int rlen;          u_char *ret, digest[EVP_MAX_MD_SIZE], 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) {
                 error("ssh_dss_sign: no DSA key");                  error("ssh_dss_sign: no DSA key");
                 return -1;                  return -1;
         }          }
         dlen = evp_md->md_size;  
         digest = xmalloc(dlen);  
         EVP_DigestInit(&md, evp_md);          EVP_DigestInit(&md, evp_md);
         EVP_DigestUpdate(&md, data, datalen);          EVP_DigestUpdate(&md, data, datalen);
         EVP_DigestFinal(&md, digest, NULL);          EVP_DigestFinal(&md, digest, &dlen);
   
         sig = DSA_do_sign(digest, dlen, key->dsa);          sig = DSA_do_sign(digest, dlen, key->dsa);
           memset(digest, 'd', sizeof(digest));
   
         if (sig == NULL) {          if (sig == NULL) {
                 fatal("ssh_dss_sign: cannot sign");                  error("ssh_dss_sign: sign failed");
                   return -1;
         }          }
         memset(digest, 0, dlen);  
         xfree(digest);  
   
         rlen = BN_num_bytes(sig->r);          rlen = BN_num_bytes(sig->r);
         slen = BN_num_bytes(sig->s);          slen = BN_num_bytes(sig->s);
Line 80 
Line 75 
                 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)
Line 114 
Line 106 
 int  int
 ssh_dss_verify(  ssh_dss_verify(
     Key *key,      Key *key,
     u_char *signature, int signaturelen,      u_char *signature, u_int signaturelen,
     u_char *data, int datalen)      u_char *data, u_int datalen)
 {  {
         Buffer b;  
         u_char *digest;  
         DSA_SIG *sig;          DSA_SIG *sig;
         EVP_MD *evp_md = EVP_sha1();          const EVP_MD *evp_md = EVP_sha1();
         EVP_MD_CTX md;          EVP_MD_CTX md;
         u_char *sigblob;          u_char digest[EVP_MAX_MD_SIZE], *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;
Line 153 
Line 130 
                 /* ietf-drafts */                  /* ietf-drafts */
                 char *ktype;                  char *ktype;
                 buffer_init(&b);                  buffer_init(&b);
                 buffer_append(&b, (char *) signature, signaturelen);                  buffer_append(&b, signature, signaturelen);
                 ktype = buffer_get_string(&b, NULL);                  ktype = buffer_get_string(&b, NULL);
                 if (strcmp("ssh-dss", ktype) != 0) {                  if (strcmp("ssh-dss", ktype) != 0) {
                         error("ssh_dss_verify: cannot handle type %s", ktype);                          error("ssh_dss_verify: cannot handle type %s", ktype);
                         buffer_free(&b);                          buffer_free(&b);
                           xfree(ktype);
                         return -1;                          return -1;
                 }                  }
                 sigblob = (u_char *)buffer_get_string(&b, &len);                  xfree(ktype);
                   sigblob = buffer_get_string(&b, &len);
                 rlen = buffer_len(&b);                  rlen = buffer_len(&b);
                 if(rlen != 0) {                  buffer_free(&b);
                         error("remaining bytes in signature %d", rlen);                  if (rlen != 0) {
                         buffer_free(&b);                          error("ssh_dss_verify: "
                               "remaining bytes in signature %d", rlen);
                           xfree(sigblob);
                         return -1;                          return -1;
                 }                  }
                 buffer_free(&b);  
                 xfree(ktype);  
         }          }
   
         if (len != SIGBLOB_LEN) {          if (len != SIGBLOB_LEN) {
Line 176 
Line 155 
         }          }
   
         /* parse signature */          /* parse signature */
         sig = DSA_SIG_new();          if ((sig = DSA_SIG_new()) == NULL)
         sig->r = BN_new();                  fatal("ssh_dss_verify: DSA_SIG_new failed");
         sig->s = BN_new();          if ((sig->r = BN_new()) == NULL)
                   fatal("ssh_dss_verify: BN_new failed");
           if ((sig->s = BN_new()) == NULL)
                   fatal("ssh_dss_verify: BN_new failed");
         BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);          BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
         BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);          BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
   
Line 188 
Line 170 
         }          }
   
         /* sha1 the data */          /* sha1 the data */
         dlen = evp_md->md_size;  
         digest = xmalloc(dlen);  
         EVP_DigestInit(&md, evp_md);          EVP_DigestInit(&md, evp_md);
         EVP_DigestUpdate(&md, data, datalen);          EVP_DigestUpdate(&md, data, datalen);
         EVP_DigestFinal(&md, digest, NULL);          EVP_DigestFinal(&md, digest, &dlen);
   
         ret = DSA_do_verify(digest, dlen, sig, key->dsa);          ret = DSA_do_verify(digest, dlen, sig, key->dsa);
           memset(digest, 'd', sizeof(digest));
   
         memset(digest, 0, dlen);  
         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;
 }  }

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.6.6.3