LCOV - code coverage report
Current view: top level - openssh-6.6p1 - ssh-dss.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 54 88 61.4 %
Date: 2014-08-01 Functions: 2 2 100.0 %
Branches: 23 52 44.2 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: ssh-dss.c,v 1.31 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
       4                 :            :  *
       5                 :            :  * Redistribution and use in source and binary forms, with or without
       6                 :            :  * modification, are permitted provided that the following conditions
       7                 :            :  * are met:
       8                 :            :  * 1. Redistributions of source code must retain the above copyright
       9                 :            :  *    notice, this list of conditions and the following disclaimer.
      10                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer in the
      12                 :            :  *    documentation and/or other materials provided with the distribution.
      13                 :            :  *
      14                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      15                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      16                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      17                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      18                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      19                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      20                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      21                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      22                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      23                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include "includes.h"
      27                 :            : 
      28                 :            : #include <sys/types.h>
      29                 :            : 
      30                 :            : #include <openssl/bn.h>
      31                 :            : #include <openssl/evp.h>
      32                 :            : 
      33                 :            : #include <stdarg.h>
      34                 :            : #include <string.h>
      35                 :            : 
      36                 :            : #include "xmalloc.h"
      37                 :            : #include "buffer.h"
      38                 :            : #include "compat.h"
      39                 :            : #include "log.h"
      40                 :            : #include "key.h"
      41                 :            : #include "digest.h"
      42                 :            : 
      43                 :            : #define INTBLOB_LEN     20
      44                 :            : #define SIGBLOB_LEN     (2*INTBLOB_LEN)
      45                 :            : 
      46                 :            : int
      47                 :         49 : ssh_dss_sign(const Key *key, u_char **sigp, u_int *lenp,
      48                 :            :     const u_char *data, u_int datalen)
      49                 :            : {
      50                 :            :         DSA_SIG *sig;
      51                 :            :         u_char digest[SSH_DIGEST_MAX_LENGTH], sigblob[SIGBLOB_LEN];
      52                 :         49 :         u_int rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
      53                 :            :         Buffer b;
      54                 :            : 
      55 [ +  - ][ +  - ]:         49 :         if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
                 [ -  + ]
      56                 :         49 :             key->dsa == NULL) {
      57                 :          0 :                 error("%s: no DSA key", __func__);
      58                 :          0 :                 return -1;
      59                 :            :         }
      60                 :            : 
      61         [ -  + ]:         49 :         if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
      62                 :            :             digest, sizeof(digest)) != 0) {
      63                 :          0 :                 error("%s: ssh_digest_memory failed", __func__);
      64                 :          0 :                 return -1;
      65                 :            :         }
      66                 :            : 
      67                 :         49 :         sig = DSA_do_sign(digest, dlen, key->dsa);
      68                 :         49 :         explicit_bzero(digest, sizeof(digest));
      69                 :            : 
      70         [ -  + ]:         49 :         if (sig == NULL) {
      71                 :          0 :                 error("ssh_dss_sign: sign failed");
      72                 :          0 :                 return -1;
      73                 :            :         }
      74                 :            : 
      75                 :         49 :         rlen = BN_num_bytes(sig->r);
      76                 :         49 :         slen = BN_num_bytes(sig->s);
      77         [ -  + ]:         49 :         if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
      78                 :          0 :                 error("bad sig size %u %u", rlen, slen);
      79                 :          0 :                 DSA_SIG_free(sig);
      80                 :          0 :                 return -1;
      81                 :            :         }
      82                 :         49 :         explicit_bzero(sigblob, SIGBLOB_LEN);
      83                 :         49 :         BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
      84                 :         49 :         BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
      85                 :         49 :         DSA_SIG_free(sig);
      86                 :            : 
      87         [ -  + ]:         49 :         if (datafellows & SSH_BUG_SIGBLOB) {
      88         [ #  # ]:          0 :                 if (lenp != NULL)
      89                 :          0 :                         *lenp = SIGBLOB_LEN;
      90         [ #  # ]:          0 :                 if (sigp != NULL) {
      91                 :          0 :                         *sigp = xmalloc(SIGBLOB_LEN);
      92                 :          0 :                         memcpy(*sigp, sigblob, SIGBLOB_LEN);
      93                 :            :                 }
      94                 :            :         } else {
      95                 :            :                 /* ietf-drafts */
      96                 :         49 :                 buffer_init(&b);
      97                 :         49 :                 buffer_put_cstring(&b, "ssh-dss");
      98                 :         49 :                 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
      99                 :         49 :                 len = buffer_len(&b);
     100         [ +  - ]:         49 :                 if (lenp != NULL)
     101                 :         49 :                         *lenp = len;
     102         [ +  - ]:         49 :                 if (sigp != NULL) {
     103                 :         49 :                         *sigp = xmalloc(len);
     104                 :         49 :                         memcpy(*sigp, buffer_ptr(&b), len);
     105                 :            :                 }
     106                 :         49 :                 buffer_free(&b);
     107                 :            :         }
     108                 :            :         return 0;
     109                 :            : }
     110                 :            : int
     111                 :         47 : ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
     112                 :            :     const u_char *data, u_int datalen)
     113                 :            : {
     114                 :            :         DSA_SIG *sig;
     115                 :            :         u_char digest[SSH_DIGEST_MAX_LENGTH], *sigblob;
     116                 :         47 :         u_int len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
     117                 :            :         int rlen, ret;
     118                 :            :         Buffer b;
     119                 :            : 
     120 [ +  - ][ +  - ]:         47 :         if (key == NULL || key_type_plain(key->type) != KEY_DSA ||
                 [ -  + ]
     121                 :         47 :             key->dsa == NULL) {
     122                 :          0 :                 error("%s: no DSA key", __func__);
     123                 :          0 :                 return -1;
     124                 :            :         }
     125                 :            : 
     126                 :            :         /* fetch signature */
     127         [ -  + ]:         47 :         if (datafellows & SSH_BUG_SIGBLOB) {
     128                 :          0 :                 sigblob = xmalloc(signaturelen);
     129                 :          0 :                 memcpy(sigblob, signature, signaturelen);
     130                 :          0 :                 len = signaturelen;
     131                 :            :         } else {
     132                 :            :                 /* ietf-drafts */
     133                 :            :                 char *ktype;
     134                 :         47 :                 buffer_init(&b);
     135                 :         47 :                 buffer_append(&b, signature, signaturelen);
     136                 :         47 :                 ktype = buffer_get_cstring(&b, NULL);
     137         [ -  + ]:         47 :                 if (strcmp("ssh-dss", ktype) != 0) {
     138                 :          0 :                         error("%s: cannot handle type %s", __func__, ktype);
     139                 :          0 :                         buffer_free(&b);
     140                 :          0 :                         free(ktype);
     141                 :          0 :                         return -1;
     142                 :            :                 }
     143                 :         47 :                 free(ktype);
     144                 :         47 :                 sigblob = buffer_get_string(&b, &len);
     145                 :         47 :                 rlen = buffer_len(&b);
     146                 :         47 :                 buffer_free(&b);
     147         [ -  + ]:         47 :                 if (rlen != 0) {
     148                 :          0 :                         error("%s: remaining bytes in signature %d",
     149                 :            :                             __func__, rlen);
     150                 :          0 :                         free(sigblob);
     151                 :          0 :                         return -1;
     152                 :            :                 }
     153                 :            :         }
     154                 :            : 
     155         [ -  + ]:         47 :         if (len != SIGBLOB_LEN) {
     156                 :          0 :                 fatal("bad sigbloblen %u != SIGBLOB_LEN", len);
     157                 :            :         }
     158                 :            : 
     159                 :            :         /* parse signature */
     160         [ -  + ]:         47 :         if ((sig = DSA_SIG_new()) == NULL)
     161                 :          0 :                 fatal("%s: DSA_SIG_new failed", __func__);
     162         [ -  + ]:         47 :         if ((sig->r = BN_new()) == NULL)
     163                 :          0 :                 fatal("%s: BN_new failed", __func__);
     164         [ -  + ]:         47 :         if ((sig->s = BN_new()) == NULL)
     165                 :          0 :                 fatal("ssh_dss_verify: BN_new failed");
     166   [ +  -  -  + ]:         94 :         if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
     167                 :         47 :             (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL))
     168                 :          0 :                 fatal("%s: BN_bin2bn failed", __func__);
     169                 :            : 
     170                 :            :         /* clean up */
     171                 :         47 :         explicit_bzero(sigblob, len);
     172                 :         47 :         free(sigblob);
     173                 :            : 
     174                 :            :         /* sha1 the data */
     175         [ -  + ]:         47 :         if (ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
     176                 :            :             digest, sizeof(digest)) != 0) {
     177                 :          0 :                 error("%s: digest_memory failed", __func__);
     178                 :          0 :                 return -1;
     179                 :            :         }
     180                 :            : 
     181                 :         47 :         ret = DSA_do_verify(digest, dlen, sig, key->dsa);
     182                 :         47 :         explicit_bzero(digest, sizeof(digest));
     183                 :            : 
     184                 :         47 :         DSA_SIG_free(sig);
     185                 :            : 
     186         [ -  + ]:         47 :         debug("%s: signature %s", __func__,
     187         [ #  # ]:          0 :             ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
     188                 :         47 :         return ret;
     189                 :            : }

Generated by: LCOV version 1.9