Fix DSA to skip EOL test when parsing mod line.
[openssl.git] / crypto / asn1 / x_long.c
index c04b192794f115cfe27385c64f8a5ae26e2f7aa9..75317418e1d85860408a5992982932cfcc3e9a02 100644 (file)
@@ -1,5 +1,5 @@
 /* x_long.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
@@ -59,6 +59,7 @@
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
+#include <openssl/bn.h>
 
 /* Custom primitive type for long handling. This converts between an ASN1_INTEGER
  * and a long directly.
@@ -69,7 +70,8 @@ static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
 static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
-static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
 
 static ASN1_PRIMITIVE_FUNCS long_pf = {
        NULL, 0,
@@ -77,7 +79,8 @@ static ASN1_PRIMITIVE_FUNCS long_pf = {
        long_free,
        long_free,      /* Clear should set to initial value */
        long_c2i,
-       long_i2c
+       long_i2c,
+       long_print
 };
 
 ASN1_ITEM_start(LONG)
@@ -104,7 +107,12 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const A
        long ltmp;
        unsigned long utmp;
        int clen, pad, i;
-       ltmp = *(long *)pval;
+       /* this exists to bypass broken gcc optimization */
+       char *cp = (char *)pval;
+
+       /* use memcpy, because we may not be long aligned */
+       memcpy(&ltmp, cp, sizeof(long));
+
        if(ltmp == it->size) return -1;
        /* Convert the long to positive: we subtract one if negative so
         * we can cleanly handle the padding if only the MSB of the leading
@@ -131,12 +139,14 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const A
        return clen + pad;
 }
 
-static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it)
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                   int utype, char *free_cont, const ASN1_ITEM *it)
 {
        int neg, i;
        long ltmp;
        unsigned long utmp = 0;
-       if(len > sizeof(long)) {
+       char *cp = (char *)pval;
+       if(len > (int)sizeof(long)) {
                ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
                return 0;
        }
@@ -158,6 +168,12 @@ static int long_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype,
                ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
                return 0;
        }
-       *(long *)pval = ltmp;
+       memcpy(cp, &ltmp, sizeof(long));
        return 1;
 }
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                       int indent, const ASN1_PCTX *pctx)
+       {
+       return BIO_printf(out, "%ld\n", *(long *)pval);
+       }