sexp2dsa.c 3.61 KB
Newer Older
1 2
/* sexp2dsa.c

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
   Copyright (C) 2002 Niels Möller

   This file is part of GNU Nettle.

   GNU Nettle is free software: you can redistribute it and/or
   modify it under the terms of either:

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at your
       option) any later version.

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at your
       option) any later version.

   or both in parallel, as here.

   GNU Nettle is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see http://www.gnu.org/licenses/.
*/
31 32

#if HAVE_CONFIG_H
33
# include "config.h"
34 35
#endif

36 37
#include <string.h>

38 39 40 41 42
#include "dsa.h"

#include "bignum.h"
#include "sexp.h"

43 44 45 46 47 48
#define GET(x, l, v)				\
do {						\
  if (!nettle_mpz_set_sexp((x), (l), (v))	\
      || mpz_sgn(x) <= 0)			\
    return 0;					\
} while(0)
49 50 51 52 53 54 55 56

/* Iterator should point past the algorithm tag, e.g.
 *
 *   (public-key (dsa (p |xxxx|) ...)
 *                    ^ here
 */

int
57 58 59
dsa_keypair_from_sexp_alist(struct dsa_params *params,
			    mpz_t pub,
			    mpz_t priv,
60 61
			    unsigned p_max_bits,
			    unsigned q_bits,
62 63
			    struct sexp_iterator *i)
{
64
  static const uint8_t * const names[5]
65 66 67
    = { "p", "q", "g", "y", "x" };
  struct sexp_iterator values[5];
  unsigned nvalues = priv ? 5 : 4;
68 69
  unsigned p_bits;

70 71 72
  if (!sexp_iterator_assoc(i, nvalues, names, values))
    return 0;

73 74 75 76 77 78 79 80 81
  GET(params->p, p_max_bits, &values[0]);
  p_bits = mpz_sizeinbase (params->p, 2);
  GET(params->q, q_bits ? q_bits : p_bits, &values[1]);
  if (q_bits > 0 && mpz_sizeinbase(params->q, 2) != q_bits)
    return 0;
  if (mpz_cmp (params->q, params->p) >= 0)
    return 0;
  GET(params->g, p_bits, &values[2]);
  if (mpz_cmp (params->g, params->p) >= 0)
82
    return 0;
83 84 85 86 87 88 89 90 91 92 93
  GET(pub, p_bits, &values[3]);
  if (mpz_cmp (pub, params->p) >= 0)
    return 0;

  if (priv)
    {
      GET(priv, mpz_sizeinbase (params->q, 2), &values[4]);
      if (mpz_cmp (priv, params->q) >= 0)
	return 0;
    }

94 95 96 97
  return 1;
}

int
98 99 100
dsa_sha1_keypair_from_sexp(struct dsa_params *params,
			   mpz_t pub,
			   mpz_t priv,
101
			   unsigned p_max_bits, 
102
			   size_t length, const uint8_t *expr)
103 104 105 106 107 108
{
  struct sexp_iterator i;

  return sexp_iterator_first(&i, length, expr)
    && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key")
    && sexp_iterator_check_type(&i, "dsa")
109 110
    && dsa_keypair_from_sexp_alist(params, pub, priv,
				   p_max_bits, DSA_SHA1_Q_BITS, &i);
111 112 113
}

int
114 115 116
dsa_sha256_keypair_from_sexp(struct dsa_params *params,
			     mpz_t pub,
			     mpz_t priv,
117
			     unsigned p_max_bits, 
118
			     size_t length, const uint8_t *expr)
119 120 121 122 123 124
{
  struct sexp_iterator i;

  return sexp_iterator_first(&i, length, expr)
    && sexp_iterator_check_type(&i, priv ? "private-key" : "public-key")
    && sexp_iterator_check_type(&i, "dsa-sha256")
125 126
    && dsa_keypair_from_sexp_alist(params, pub, priv,
				   p_max_bits, DSA_SHA256_Q_BITS, &i);
127 128
}

129 130
int
dsa_signature_from_sexp(struct dsa_signature *rs,
131 132
			struct sexp_iterator *i,
			unsigned q_bits)
133
{
134
  static const uint8_t * const names[2] = { "r", "s" };
135 136 137 138 139
  struct sexp_iterator values[2];

  if (!sexp_iterator_assoc(i, 2, names, values))
    return 0;

140 141
  GET(rs->r, q_bits, &values[0]);
  GET(rs->s, q_bits, &values[1]);
142 143 144

  return 1;
}