Make sure bs is assigned NULL when it's free'd, or there will be an
[openssl.git] / crypto / dsa / dsa_asn1.c
1 /* crypto/dsa/dsa_asn1.c */
2
3 #include <stdio.h>
4 #include "cryptlib.h"
5 #include <openssl/dsa.h>
6 #include <openssl/asn1.h>
7 #include <openssl/asn1_mac.h>
8
9 DSA_SIG *DSA_SIG_new(void)
10 {
11         DSA_SIG *ret;
12
13         ret = OPENSSL_malloc(sizeof(DSA_SIG));
14         if (ret == NULL)
15                 {
16                 DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE);
17                 return(NULL);
18                 }
19         ret->r = NULL;
20         ret->s = NULL;
21         return(ret);
22 }
23
24 void DSA_SIG_free(DSA_SIG *r)
25 {
26         if (r == NULL) return;
27         if (r->r) BN_clear_free(r->r);
28         if (r->s) BN_clear_free(r->s);
29         OPENSSL_free(r);
30 }
31
32 int i2d_DSA_SIG(const DSA_SIG *v, unsigned char **pp)
33 {
34         int t=0,len;
35         ASN1_INTEGER rbs,sbs;
36         unsigned char *p;
37
38         rbs.data=OPENSSL_malloc(BN_num_bits(v->r)/8+1);
39         if (rbs.data == NULL)
40                 {
41                 DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
42                 return(0);
43                 }
44         rbs.type=V_ASN1_INTEGER;
45         rbs.length=BN_bn2bin(v->r,rbs.data);
46         sbs.data=OPENSSL_malloc(BN_num_bits(v->s)/8+1);
47         if (sbs.data == NULL)
48                 {
49                 OPENSSL_free(rbs.data);
50                 DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
51                 return(0);
52                 }
53         sbs.type=V_ASN1_INTEGER;
54         sbs.length=BN_bn2bin(v->s,sbs.data);
55
56         len=i2d_ASN1_INTEGER(&rbs,NULL);
57         len+=i2d_ASN1_INTEGER(&sbs,NULL);
58
59         if (pp)
60                 {
61                 p=*pp;
62                 ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
63                 i2d_ASN1_INTEGER(&rbs,&p);
64                 i2d_ASN1_INTEGER(&sbs,&p);
65                 }
66         t=ASN1_object_size(1,len,V_ASN1_SEQUENCE);
67         OPENSSL_free(rbs.data);
68         OPENSSL_free(sbs.data);
69         return(t);
70 }
71
72 DSA_SIG *d2i_DSA_SIG(DSA_SIG **a, const unsigned char **pp, long length)
73 {
74         int i=ERR_R_NESTED_ASN1_ERROR;
75         ASN1_INTEGER *bs=NULL;
76         M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new);
77
78         M_ASN1_D2I_Init();
79         M_ASN1_D2I_start_sequence();
80         M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
81         if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL)
82                 goto err_bn;
83         M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
84         if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL)
85                 goto err_bn;
86         M_ASN1_BIT_STRING_free(bs);
87         bs = NULL;
88         M_ASN1_D2I_Finish_2(a);
89
90 err_bn:
91         i=ERR_R_BN_LIB;
92 err:
93         DSAerr(DSA_F_D2I_DSA_SIG,i);
94         if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret);
95         if (bs != NULL) M_ASN1_BIT_STRING_free(bs);
96         return(NULL);
97 }