summaryrefslogtreecommitdiffstats
path: root/crypto/dsa/dsa_asn1.c
diff options
context:
space:
mode:
authorUlf Möller <ulf@openssl.org>1999-04-09 16:24:32 +0000
committerUlf Möller <ulf@openssl.org>1999-04-09 16:24:32 +0000
commita8da89186c447932b9f5abced708330a3bff313b (patch)
tree0a2db3e074643271b2300dbd19fc0c93f86fd9d9 /crypto/dsa/dsa_asn1.c
parentdae08db4a0d8bb972315988150187c9f091c557e (diff)
Separate DSA functionality from ASN.1 encoding.
New functions DSA_do_sign and DSA_do_verify to provide access to the raw DSA values.
Diffstat (limited to 'crypto/dsa/dsa_asn1.c')
-rw-r--r--crypto/dsa/dsa_asn1.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
new file mode 100644
index 0000000000..b7fa7eda4f
--- /dev/null
+++ b/crypto/dsa/dsa_asn1.c
@@ -0,0 +1,102 @@
+/* crypto/dsa/dsa_asn1.c */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include "dsa.h"
+#include "asn1.h"
+#include "asn1_mac.h"
+
+DSA_SIG *DSA_SIG_new(void)
+{
+ DSA_SIG *ret;
+
+ ret = Malloc(sizeof(DSA_SIG));
+ if (ret == NULL)
+ {
+ DSAerr(DSA_F_DSA_SIG_NEW,ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+ ret->r = NULL;
+ ret->s = NULL;
+ return(ret);
+}
+
+void DSA_SIG_free(r)
+DSA_SIG *r;
+{
+ if (r == NULL) return;
+ if (r->r) BN_clear_free(r->r);
+ if (r->s) BN_clear_free(r->s);
+ Free(r);
+}
+
+int i2d_DSA_SIG(v,pp)
+DSA_SIG *v;
+unsigned char **pp;
+{
+ int t=0,len;
+ ASN1_INTEGER rbs,sbs;
+ unsigned char *p;
+
+ rbs.data=Malloc(BN_num_bits(v->r)/8+1);
+ if (rbs.data == NULL)
+ {
+ DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+ rbs.type=V_ASN1_INTEGER;
+ rbs.length=BN_bn2bin(v->r,rbs.data);
+ sbs.data=Malloc(BN_num_bits(v->s)/8+1);
+ if (sbs.data == NULL)
+ {
+ Free(rbs.data);
+ DSAerr(DSA_F_I2D_DSA_SIG, ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+ sbs.type=V_ASN1_INTEGER;
+ sbs.length=BN_bn2bin(v->s,sbs.data);
+
+ len=i2d_ASN1_INTEGER(&rbs,NULL);
+ len+=i2d_ASN1_INTEGER(&sbs,NULL);
+
+ if (pp)
+ {
+ p=*pp;
+ ASN1_put_object(&p,1,len,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+ i2d_ASN1_INTEGER(&rbs,&p);
+ i2d_ASN1_INTEGER(&sbs,&p);
+ }
+ t=ASN1_object_size(1,len,V_ASN1_SEQUENCE);
+ Free(rbs.data);
+ Free(sbs.data);
+ return(t);
+}
+
+DSA_SIG *d2i_DSA_SIG(a,pp,length)
+DSA_SIG **a;
+unsigned char **pp;
+long length;
+{
+ int i=ERR_R_NESTED_ASN1_ERROR;
+ ASN1_INTEGER *bs=NULL;
+ M_ASN1_D2I_vars(a,DSA_SIG *,DSA_SIG_new);
+
+ M_ASN1_D2I_Init();
+ M_ASN1_D2I_start_sequence();
+ M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+ if ((ret->r=BN_bin2bn(bs->data,bs->length,ret->r)) == NULL)
+ goto err_bn;
+ M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
+ if ((ret->s=BN_bin2bn(bs->data,bs->length,ret->s)) == NULL)
+ goto err_bn;
+ ASN1_BIT_STRING_free(bs);
+ M_ASN1_D2I_Finish_2(a);
+
+err_bn:
+ i=ERR_R_BN_LIB;
+err:
+ DSAerr(DSA_F_D2I_DSA_SIG,i);
+ if ((ret != NULL) && ((a == NULL) || (*a != ret))) DSA_SIG_free(ret);
+ if (bs != NULL) ASN1_BIT_STRING_free(bs);
+ return(NULL);
+}