#include <stdio.h>
#include "cryptlib.h"
-#include <openssl/asn1_mac.h>
+#include <openssl/asn1t.h>
#include <openssl/x509.h>
-int i2d_X509_PUBKEY(X509_PUBKEY *a, unsigned char **pp)
- {
- M_ASN1_I2D_vars(a);
-
- M_ASN1_I2D_len(a->algor, i2d_X509_ALGOR);
- M_ASN1_I2D_len(a->public_key, i2d_ASN1_BIT_STRING);
-
- M_ASN1_I2D_seq_total();
-
- M_ASN1_I2D_put(a->algor, i2d_X509_ALGOR);
- M_ASN1_I2D_put(a->public_key, i2d_ASN1_BIT_STRING);
-
- M_ASN1_I2D_finish();
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+ if(operation == ASN1_OP_FREE_POST) {
+ X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+ EVP_PKEY_free(pubkey->pkey);
}
+ return 1;
+}
-X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **a, unsigned char **pp,
- long length)
- {
- M_ASN1_D2I_vars(a,X509_PUBKEY *,X509_PUBKEY_new);
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
- M_ASN1_D2I_Init();
- M_ASN1_D2I_start_sequence();
- M_ASN1_D2I_get(ret->algor,d2i_X509_ALGOR);
- M_ASN1_D2I_get(ret->public_key,d2i_ASN1_BIT_STRING);
- if (ret->pkey != NULL)
- {
- EVP_PKEY_free(ret->pkey);
- ret->pkey=NULL;
- }
- M_ASN1_D2I_Finish(a,X509_PUBKEY_free,ASN1_F_D2I_X509_PUBKEY);
- }
-
-X509_PUBKEY *X509_PUBKEY_new(void)
- {
- X509_PUBKEY *ret=NULL;
- ASN1_CTX c;
-
- M_ASN1_New_Malloc(ret,X509_PUBKEY);
- M_ASN1_New(ret->algor,X509_ALGOR_new);
- M_ASN1_New(ret->public_key,M_ASN1_BIT_STRING_new);
- ret->pkey=NULL;
- return(ret);
- M_ASN1_New_Error(ASN1_F_X509_PUBKEY_NEW);
- }
-
-void X509_PUBKEY_free(X509_PUBKEY *a)
- {
- if (a == NULL) return;
- X509_ALGOR_free(a->algor);
- M_ASN1_BIT_STRING_free(a->public_key);
- if (a->pkey != NULL) EVP_PKEY_free(a->pkey);
- Free((char *)a);
- }
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
}
}
else
-#ifndef NO_DSA
+#ifndef OPENSSL_NO_DSA
if (pkey->type == EVP_PKEY_DSA)
{
unsigned char *pp;
dsa->write_params=0;
ASN1_TYPE_free(a->parameter);
i=i2d_DSAparams(dsa,NULL);
- p=(unsigned char *)Malloc(i);
+ p=(unsigned char *)OPENSSL_malloc(i);
pp=p;
i2d_DSAparams(dsa,&pp);
a->parameter=ASN1_TYPE_new();
a->parameter->type=V_ASN1_SEQUENCE;
a->parameter->value.sequence=ASN1_STRING_new();
ASN1_STRING_set(a->parameter->value.sequence,p,i);
- Free(p);
+ OPENSSL_free(p);
}
else
#endif
}
if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err;
- if ((s=(unsigned char *)Malloc(i+1)) == NULL) goto err;
+ if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) goto err;
p=s;
i2d_PublicKey(pkey,&p);
if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err;
pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
- Free(s);
+ OPENSSL_free(s);
+#if 0
CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
pk->pkey=pkey;
+#endif
if (*x != NULL)
X509_PUBKEY_free(*x);
long j;
int type;
unsigned char *p;
-#ifndef NO_DSA
+#ifndef OPENSSL_NO_DSA
+ const unsigned char *cp;
X509_ALGOR *a;
#endif
}
ret->save_parameters=0;
-#ifndef NO_DSA
+#ifndef OPENSSL_NO_DSA
a=key->algor;
if (ret->type == EVP_PKEY_DSA)
{
- if (a->parameter->type == V_ASN1_SEQUENCE)
+ if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE))
{
ret->pkey.dsa->write_params=0;
- p=a->parameter->value.sequence->data;
+ cp=p=a->parameter->value.sequence->data;
j=a->parameter->value.sequence->length;
- if (!d2i_DSAparams(&ret->pkey.dsa,&p,(long)j))
+ if (!d2i_DSAparams(&ret->pkey.dsa,&cp,(long)j))
goto err;
}
ret->save_parameters=1;
return(NULL);
}
+/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
+ * and encode or decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp,
+ long length)
+{
+ X509_PUBKEY *xpk;
+ EVP_PKEY *pktmp;
+ xpk = d2i_X509_PUBKEY(NULL, pp, length);
+ if(!xpk) return NULL;
+ pktmp = X509_PUBKEY_get(xpk);
+ X509_PUBKEY_free(xpk);
+ if(!pktmp) return NULL;
+ if(a) {
+ EVP_PKEY_free(*a);
+ *a = pktmp;
+ }
+ return pktmp;
+}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+ X509_PUBKEY *xpk=NULL;
+ int ret;
+ if(!a) return 0;
+ if(!X509_PUBKEY_set(&xpk, a)) return 0;
+ ret = i2d_X509_PUBKEY(xpk, pp);
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/* The following are equivalents but which return RSA and DSA
+ * keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, unsigned char **pp,
+ long length)
+{
+ EVP_PKEY *pkey;
+ RSA *key;
+ unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if(!pkey) return NULL;
+ key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if(!key) return NULL;
+ *pp = q;
+ if(a) {
+ RSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if(!a) return 0;
+ pktmp = EVP_PKEY_new();
+ if(!pktmp) {
+ ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_RSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, unsigned char **pp,
+ long length)
+{
+ EVP_PKEY *pkey;
+ DSA *key;
+ unsigned char *q;
+ q = *pp;
+ pkey = d2i_PUBKEY(NULL, &q, length);
+ if(!pkey) return NULL;
+ key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if(!key) return NULL;
+ *pp = q;
+ if(a) {
+ DSA_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+ EVP_PKEY *pktmp;
+ int ret;
+ if(!a) return 0;
+ pktmp = EVP_PKEY_new();
+ if(!pktmp) {
+ ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ EVP_PKEY_set1_DSA(pktmp, a);
+ ret = i2d_PUBKEY(pktmp, pp);
+ EVP_PKEY_free(pktmp);
+ return ret;
+}
+#endif