diff options
author | Bodo Möller <bodo@openssl.org> | 2002-02-13 18:21:51 +0000 |
---|---|---|
committer | Bodo Möller <bodo@openssl.org> | 2002-02-13 18:21:51 +0000 |
commit | 4d94ae00d5614d64d4dd065860c4b00161a81f82 (patch) | |
tree | e993aa323ea753b3c0782439eb78f4f8c896a67e /crypto/asn1/x_pubkey.c | |
parent | 60d8bae30d1040a4f955e3247443b2dd4c674cde (diff) | |
download | openssl-4d94ae00d5614d64d4dd065860c4b00161a81f82.zip openssl-4d94ae00d5614d64d4dd065860c4b00161a81f82.tar.gz openssl-4d94ae00d5614d64d4dd065860c4b00161a81f82.tar.bz2 |
ECDSA support
Submitted by: Nils Larsch <nla@trustcenter.de>
Diffstat (limited to 'crypto/asn1/x_pubkey.c')
-rw-r--r-- | crypto/asn1/x_pubkey.c | 223 |
1 files changed, 174 insertions, 49 deletions
diff --git a/crypto/asn1/x_pubkey.c b/crypto/asn1/x_pubkey.c index 5563029..227b0ce 100644 --- a/crypto/asn1/x_pubkey.c +++ b/crypto/asn1/x_pubkey.c @@ -63,13 +63,14 @@ /* 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) { + { + if (operation == ASN1_OP_FREE_POST) + { X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; EVP_PKEY_free(pubkey->pkey); - } + } return 1; -} + } ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), @@ -108,13 +109,12 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) a->parameter->type=V_ASN1_NULL; } } - else #ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) + else if (pkey->type == EVP_PKEY_DSA) { unsigned char *pp; DSA *dsa; - + dsa=pkey->pkey.dsa; dsa->write_params=0; ASN1_TYPE_free(a->parameter); @@ -128,8 +128,51 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) ASN1_STRING_set(a->parameter->value.sequence,p,i); OPENSSL_free(p); } - else #endif +#ifndef OPENSSL_NO_ECDSA + else if (pkey->type == EVP_PKEY_ECDSA) + { + unsigned char *pp; + ECDSA *ecdsa; + + ecdsa = pkey->pkey.ecdsa; + ecdsa->write_params=0; + ASN1_TYPE_free(a->parameter); + if ((i = i2d_ECDSAParameters(ecdsa, NULL)) == 0) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ECDSA_LIB); + goto err; + } + if ((p = (unsigned char *) OPENSSL_malloc(i)) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE); + goto err; + } + pp = p; + if (!i2d_ECDSAParameters(ecdsa, &pp)) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ECDSA_LIB); + OPENSSL_free(p); + goto err; + } + if ((a->parameter = ASN1_TYPE_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); + OPENSSL_free(p); + goto err; + } + a->parameter->type = V_ASN1_SEQUENCE; + if ((a->parameter->value.sequence = ASN1_STRING_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_SET, ERR_R_ASN1_LIB); + OPENSSL_free(p); + goto err; + } + ASN1_STRING_set(a->parameter->value.sequence, p, i); + OPENSSL_free(p); + } +#endif + else if (1) { X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM); goto err; @@ -177,40 +220,79 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) if (key == NULL) goto err; if (key->pkey != NULL) - { - CRYPTO_add(&key->pkey->references,1,CRYPTO_LOCK_EVP_PKEY); - return(key->pkey); - } + { + CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return(key->pkey); + } if (key->public_key == NULL) goto err; type=OBJ_obj2nid(key->algor->algorithm); - p=key->public_key->data; - j=key->public_key->length; - if ((ret=d2i_PublicKey(type,NULL,&p,(long)j)) == NULL) + if ((ret = EVP_PKEY_new()) == NULL) { - X509err(X509_F_X509_PUBKEY_GET,X509_R_ERR_ASN1_LIB); + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); goto err; } - ret->save_parameters=0; + ret->type = EVP_PKEY_type(type); -#ifndef OPENSSL_NO_DSA + /* the parameters must be extracted before the public key (ECDSA!) */ + a=key->algor; - if (ret->type == EVP_PKEY_DSA) + + if (0) + ; +#ifndef OPENSSL_NO_DSA + else if (ret->type == EVP_PKEY_DSA) { if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) { + if ((ret->pkey.dsa = DSA_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); + goto err; + } ret->pkey.dsa->write_params=0; cp=p=a->parameter->value.sequence->data; j=a->parameter->value.sequence->length; - if (!d2i_DSAparams(&ret->pkey.dsa,&cp,(long)j)) + if (!d2i_DSAparams(&ret->pkey.dsa, &cp, (long)j)) goto err; } ret->save_parameters=1; } #endif - key->pkey=ret; - CRYPTO_add(&ret->references,1,CRYPTO_LOCK_EVP_PKEY); +#ifndef OPENSSL_NO_ECDSA + else if (ret->type == EVP_PKEY_ECDSA) + { + if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) + { + if ((ret->pkey.ecdsa= ECDSA_new()) == NULL) + { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->pkey.ecdsa->write_params = 0; + cp = p = a->parameter->value.sequence->data; + j = a->parameter->value.sequence->length; + if (!d2i_ECDSAParameters(&ret->pkey.ecdsa, &cp, (long)j)) + { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_ECDSA_LIB); + goto err; + } + } + ret->save_parameters = 1; + } +#endif + + p=key->public_key->data; + j=key->public_key->length; + if ((ret = d2i_PublicKey(type, &ret, &p, (long)j)) == NULL) + { + X509err(X509_F_X509_PUBKEY_GET, X509_R_ERR_ASN1_LIB); + goto err; + } + + key->pkey = ret; + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); return(ret); err: if (ret != NULL) @@ -224,7 +306,7 @@ err: 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); @@ -232,15 +314,16 @@ EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp, pktmp = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); if(!pktmp) return NULL; - if(a) { + 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; @@ -248,7 +331,7 @@ int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) ret = i2d_X509_PUBKEY(xpk, pp); X509_PUBKEY_free(xpk); return ret; -} + } /* The following are equivalents but which return RSA and DSA * keys @@ -256,75 +339,117 @@ int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) #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; + if (!pkey) return NULL; key = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); - if(!key) return NULL; + if (!key) return NULL; *pp = q; - if(a) { + 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; + if (!a) return 0; pktmp = EVP_PKEY_new(); - if(!pktmp) { + 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; + if (!pkey) return NULL; key = EVP_PKEY_get1_DSA(pkey); EVP_PKEY_free(pkey); - if(!key) return NULL; + if (!key) return NULL; *pp = q; - if(a) { + 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) { + 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 + +#ifndef OPENSSL_NO_ECDSA +ECDSA *d2i_ECDSA_PUBKEY(ECDSA **a, unsigned char **pp, long length) + { + EVP_PKEY *pkey; + ECDSA *key; + unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) return(NULL); + key = EVP_PKEY_get1_ECDSA(pkey); + EVP_PKEY_free(pkey); + if (!key) return(NULL); + *pp = q; + if (a) + { + ECDSA_free(*a); + *a = key; + } + return(key); + } + +int i2d_ECDSA_PUBKEY(ECDSA *a, unsigned char **pp) + { + EVP_PKEY *pktmp; + int ret; + if (!a) return(0); + if ((pktmp = EVP_PKEY_new()) == NULL) + { + ASN1err(ASN1_F_I2D_ECDSA_PUBKEY, ERR_R_MALLOC_FAILURE); + return(0); + } + EVP_PKEY_set1_ECDSA(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return(ret); + } #endif |