Home | History | Annotate | Download | only in dsa
      1 /* Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL
      2  * project 2000. */
      3 /* ====================================================================
      4  * Copyright (c) 2000-2005 The OpenSSL Project.  All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  *
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  *
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in
     15  *    the documentation and/or other materials provided with the
     16  *    distribution.
     17  *
     18  * 3. All advertising materials mentioning features or use of this
     19  *    software must display the following acknowledgment:
     20  *    "This product includes software developed by the OpenSSL Project
     21  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     22  *
     23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     24  *    endorse or promote products derived from this software without
     25  *    prior written permission. For written permission, please contact
     26  *    licensing (at) OpenSSL.org.
     27  *
     28  * 5. Products derived from this software may not be called "OpenSSL"
     29  *    nor may "OpenSSL" appear in their names without prior written
     30  *    permission of the OpenSSL Project.
     31  *
     32  * 6. Redistributions of any form whatsoever must retain the following
     33  *    acknowledgment:
     34  *    "This product includes software developed by the OpenSSL Project
     35  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     36  *
     37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     48  * OF THE POSSIBILITY OF SUCH DAMAGE.
     49  * ====================================================================
     50  *
     51  * This product includes cryptographic software written by Eric Young
     52  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     53  * Hudson (tjh (at) cryptsoft.com). */
     54 
     55 #include <openssl/dsa.h>
     56 
     57 #include <assert.h>
     58 
     59 #include <openssl/bn.h>
     60 #include <openssl/bytestring.h>
     61 #include <openssl/err.h>
     62 #include <openssl/mem.h>
     63 
     64 #include "../bytestring/internal.h"
     65 
     66 
     67 static int parse_integer(CBS *cbs, BIGNUM **out) {
     68   assert(*out == NULL);
     69   *out = BN_new();
     70   if (*out == NULL) {
     71     return 0;
     72   }
     73   return BN_parse_asn1_unsigned(cbs, *out);
     74 }
     75 
     76 static int marshal_integer(CBB *cbb, BIGNUM *bn) {
     77   if (bn == NULL) {
     78     // A DSA object may be missing some components.
     79     OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER);
     80     return 0;
     81   }
     82   return BN_marshal_asn1(cbb, bn);
     83 }
     84 
     85 DSA_SIG *DSA_SIG_parse(CBS *cbs) {
     86   DSA_SIG *ret = DSA_SIG_new();
     87   if (ret == NULL) {
     88     return NULL;
     89   }
     90   CBS child;
     91   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
     92       !parse_integer(&child, &ret->r) ||
     93       !parse_integer(&child, &ret->s) ||
     94       CBS_len(&child) != 0) {
     95     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
     96     DSA_SIG_free(ret);
     97     return NULL;
     98   }
     99   return ret;
    100 }
    101 
    102 int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) {
    103   CBB child;
    104   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
    105       !marshal_integer(&child, sig->r) ||
    106       !marshal_integer(&child, sig->s) ||
    107       !CBB_flush(cbb)) {
    108     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
    109     return 0;
    110   }
    111   return 1;
    112 }
    113 
    114 DSA *DSA_parse_public_key(CBS *cbs) {
    115   DSA *ret = DSA_new();
    116   if (ret == NULL) {
    117     return NULL;
    118   }
    119   CBS child;
    120   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
    121       !parse_integer(&child, &ret->pub_key) ||
    122       !parse_integer(&child, &ret->p) ||
    123       !parse_integer(&child, &ret->q) ||
    124       !parse_integer(&child, &ret->g) ||
    125       CBS_len(&child) != 0) {
    126     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
    127     DSA_free(ret);
    128     return NULL;
    129   }
    130   return ret;
    131 }
    132 
    133 int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) {
    134   CBB child;
    135   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
    136       !marshal_integer(&child, dsa->pub_key) ||
    137       !marshal_integer(&child, dsa->p) ||
    138       !marshal_integer(&child, dsa->q) ||
    139       !marshal_integer(&child, dsa->g) ||
    140       !CBB_flush(cbb)) {
    141     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
    142     return 0;
    143   }
    144   return 1;
    145 }
    146 
    147 DSA *DSA_parse_parameters(CBS *cbs) {
    148   DSA *ret = DSA_new();
    149   if (ret == NULL) {
    150     return NULL;
    151   }
    152   CBS child;
    153   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
    154       !parse_integer(&child, &ret->p) ||
    155       !parse_integer(&child, &ret->q) ||
    156       !parse_integer(&child, &ret->g) ||
    157       CBS_len(&child) != 0) {
    158     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
    159     DSA_free(ret);
    160     return NULL;
    161   }
    162   return ret;
    163 }
    164 
    165 int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) {
    166   CBB child;
    167   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
    168       !marshal_integer(&child, dsa->p) ||
    169       !marshal_integer(&child, dsa->q) ||
    170       !marshal_integer(&child, dsa->g) ||
    171       !CBB_flush(cbb)) {
    172     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
    173     return 0;
    174   }
    175   return 1;
    176 }
    177 
    178 DSA *DSA_parse_private_key(CBS *cbs) {
    179   DSA *ret = DSA_new();
    180   if (ret == NULL) {
    181     return NULL;
    182   }
    183 
    184   CBS child;
    185   uint64_t version;
    186   if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
    187       !CBS_get_asn1_uint64(&child, &version)) {
    188     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
    189     goto err;
    190   }
    191 
    192   if (version != 0) {
    193     OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION);
    194     goto err;
    195   }
    196 
    197   if (!parse_integer(&child, &ret->p) ||
    198       !parse_integer(&child, &ret->q) ||
    199       !parse_integer(&child, &ret->g) ||
    200       !parse_integer(&child, &ret->pub_key) ||
    201       !parse_integer(&child, &ret->priv_key) ||
    202       CBS_len(&child) != 0) {
    203     OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR);
    204     goto err;
    205   }
    206   return ret;
    207 
    208 err:
    209   DSA_free(ret);
    210   return NULL;
    211 }
    212 
    213 int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) {
    214   CBB child;
    215   if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
    216       !CBB_add_asn1_uint64(&child, 0 /* version */) ||
    217       !marshal_integer(&child, dsa->p) ||
    218       !marshal_integer(&child, dsa->q) ||
    219       !marshal_integer(&child, dsa->g) ||
    220       !marshal_integer(&child, dsa->pub_key) ||
    221       !marshal_integer(&child, dsa->priv_key) ||
    222       !CBB_flush(cbb)) {
    223     OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR);
    224     return 0;
    225   }
    226   return 1;
    227 }
    228 
    229 DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) {
    230   if (len < 0) {
    231     return NULL;
    232   }
    233   CBS cbs;
    234   CBS_init(&cbs, *inp, (size_t)len);
    235   DSA_SIG *ret = DSA_SIG_parse(&cbs);
    236   if (ret == NULL) {
    237     return NULL;
    238   }
    239   if (out_sig != NULL) {
    240     DSA_SIG_free(*out_sig);
    241     *out_sig = ret;
    242   }
    243   *inp = CBS_data(&cbs);
    244   return ret;
    245 }
    246 
    247 int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) {
    248   CBB cbb;
    249   if (!CBB_init(&cbb, 0) ||
    250       !DSA_SIG_marshal(&cbb, in)) {
    251     CBB_cleanup(&cbb);
    252     return -1;
    253   }
    254   return CBB_finish_i2d(&cbb, outp);
    255 }
    256 
    257 DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) {
    258   if (len < 0) {
    259     return NULL;
    260   }
    261   CBS cbs;
    262   CBS_init(&cbs, *inp, (size_t)len);
    263   DSA *ret = DSA_parse_public_key(&cbs);
    264   if (ret == NULL) {
    265     return NULL;
    266   }
    267   if (out != NULL) {
    268     DSA_free(*out);
    269     *out = ret;
    270   }
    271   *inp = CBS_data(&cbs);
    272   return ret;
    273 }
    274 
    275 int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) {
    276   CBB cbb;
    277   if (!CBB_init(&cbb, 0) ||
    278       !DSA_marshal_public_key(&cbb, in)) {
    279     CBB_cleanup(&cbb);
    280     return -1;
    281   }
    282   return CBB_finish_i2d(&cbb, outp);
    283 }
    284 
    285 DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) {
    286   if (len < 0) {
    287     return NULL;
    288   }
    289   CBS cbs;
    290   CBS_init(&cbs, *inp, (size_t)len);
    291   DSA *ret = DSA_parse_private_key(&cbs);
    292   if (ret == NULL) {
    293     return NULL;
    294   }
    295   if (out != NULL) {
    296     DSA_free(*out);
    297     *out = ret;
    298   }
    299   *inp = CBS_data(&cbs);
    300   return ret;
    301 }
    302 
    303 int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) {
    304   CBB cbb;
    305   if (!CBB_init(&cbb, 0) ||
    306       !DSA_marshal_private_key(&cbb, in)) {
    307     CBB_cleanup(&cbb);
    308     return -1;
    309   }
    310   return CBB_finish_i2d(&cbb, outp);
    311 }
    312 
    313 DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) {
    314   if (len < 0) {
    315     return NULL;
    316   }
    317   CBS cbs;
    318   CBS_init(&cbs, *inp, (size_t)len);
    319   DSA *ret = DSA_parse_parameters(&cbs);
    320   if (ret == NULL) {
    321     return NULL;
    322   }
    323   if (out != NULL) {
    324     DSA_free(*out);
    325     *out = ret;
    326   }
    327   *inp = CBS_data(&cbs);
    328   return ret;
    329 }
    330 
    331 int i2d_DSAparams(const DSA *in, uint8_t **outp) {
    332   CBB cbb;
    333   if (!CBB_init(&cbb, 0) ||
    334       !DSA_marshal_parameters(&cbb, in)) {
    335     CBB_cleanup(&cbb);
    336     return -1;
    337   }
    338   return CBB_finish_i2d(&cbb, outp);
    339 }
    340