Various function for commmon operations.
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -3,6 +3,12 @@
|
|||||||
|
|
||||||
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
|
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
|
||||||
|
|
||||||
|
*) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
|
||||||
|
in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
|
||||||
|
structure from a certificate. X509_pubkey_digest() digests tha public_key
|
||||||
|
contents: this is used in various key identifiers.
|
||||||
|
[Steve Henson]
|
||||||
|
|
||||||
*) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
|
*) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
|
||||||
keyUsage if basicConstraints absent for a CA.
|
keyUsage if basicConstraints absent for a CA.
|
||||||
[Steve Henson]
|
[Steve Henson]
|
||||||
|
@@ -525,7 +525,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial, X509 *issuer,
|
|||||||
if(!*req) *req = OCSP_REQUEST_new();
|
if(!*req) *req = OCSP_REQUEST_new();
|
||||||
if(!*req) goto err;
|
if(!*req) goto err;
|
||||||
iname = X509_get_subject_name(issuer);
|
iname = X509_get_subject_name(issuer);
|
||||||
ikey = issuer->cert_info->key->public_key;
|
ikey = X509_get0_pubkey_bitstr(issuer);
|
||||||
sno = s2i_ASN1_INTEGER(NULL, serial);
|
sno = s2i_ASN1_INTEGER(NULL, serial);
|
||||||
if(!sno)
|
if(!sno)
|
||||||
{
|
{
|
||||||
|
@@ -74,7 +74,6 @@
|
|||||||
int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data,
|
int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data,
|
||||||
unsigned char *md, unsigned int *len)
|
unsigned char *md, unsigned int *len)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
int i;
|
int i;
|
||||||
unsigned char *str,*p;
|
unsigned char *str,*p;
|
||||||
|
|
||||||
@@ -83,9 +82,7 @@ int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data,
|
|||||||
p=str;
|
p=str;
|
||||||
i2d(data,&p);
|
i2d(data,&p);
|
||||||
|
|
||||||
EVP_DigestInit(&ctx,type);
|
EVP_Digest(str, i, md, len, type);
|
||||||
EVP_DigestUpdate(&ctx,str,i);
|
|
||||||
EVP_DigestFinal(&ctx,md,len);
|
|
||||||
OPENSSL_free(str);
|
OPENSSL_free(str);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
@@ -96,16 +93,13 @@ int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data,
|
|||||||
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
|
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
|
||||||
unsigned char *md, unsigned int *len)
|
unsigned char *md, unsigned int *len)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
int i;
|
int i;
|
||||||
unsigned char *str = NULL;
|
unsigned char *str = NULL;
|
||||||
|
|
||||||
i=ASN1_item_i2d(asn,&str, it);
|
i=ASN1_item_i2d(asn,&str, it);
|
||||||
if (!str) return(0);
|
if (!str) return(0);
|
||||||
|
|
||||||
EVP_DigestInit(&ctx,type);
|
EVP_Digest(str, i, md, len, type);
|
||||||
EVP_DigestUpdate(&ctx,str,i);
|
|
||||||
EVP_DigestFinal(&ctx,md,len);
|
|
||||||
OPENSSL_free(str);
|
OPENSSL_free(str);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
@@ -196,14 +196,11 @@ int i2d_RSA_NET(const RSA *a, unsigned char **pp, int (*cb)(), int sgckey)
|
|||||||
i = strlen((char *)buf);
|
i = strlen((char *)buf);
|
||||||
/* If the key is used for SGC the algorithm is modified a little. */
|
/* If the key is used for SGC the algorithm is modified a little. */
|
||||||
if(sgckey) {
|
if(sgckey) {
|
||||||
EVP_MD_CTX mctx;
|
EVP_Digest(buf, i, buf, NULL, EVP_md5());
|
||||||
EVP_DigestInit(&mctx, EVP_md5());
|
|
||||||
EVP_DigestUpdate(&mctx, buf, i);
|
|
||||||
EVP_DigestFinal(&mctx, buf, NULL);
|
|
||||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||||
i = 26;
|
i = 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
|
EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
|
||||||
memset(buf,0,256);
|
memset(buf,0,256);
|
||||||
|
|
||||||
@@ -287,10 +284,7 @@ static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
|
|||||||
|
|
||||||
i = strlen((char *)buf);
|
i = strlen((char *)buf);
|
||||||
if(sgckey){
|
if(sgckey){
|
||||||
EVP_MD_CTX mctx;
|
EVP_Digest(buf, i, buf, NULL, EVP_md5());
|
||||||
EVP_DigestInit(&mctx, EVP_md5());
|
|
||||||
EVP_DigestUpdate(&mctx, buf, i);
|
|
||||||
EVP_DigestFinal(&mctx, buf, NULL);
|
|
||||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||||
i = 26;
|
i = 26;
|
||||||
}
|
}
|
||||||
|
@@ -89,4 +89,14 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, EVP_MD_CTX *in)
|
|||||||
}
|
}
|
||||||
memcpy((char *)out,(char *)in,in->digest->ctx_size);
|
memcpy((char *)out,(char *)in,in->digest->ctx_size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EVP_Digest(void *data, unsigned int count,
|
||||||
|
unsigned char *md, unsigned int *size, const EVP_MD *type)
|
||||||
|
{
|
||||||
|
EVP_MD_CTX ctx;
|
||||||
|
EVP_DigestInit(&ctx, type);
|
||||||
|
EVP_DigestUpdate(&ctx, data, count);
|
||||||
|
EVP_DigestFinal(&ctx, md, size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -559,6 +559,8 @@ void EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
|
|||||||
void EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
|
void EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
|
||||||
unsigned int cnt);
|
unsigned int cnt);
|
||||||
void EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
|
void EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
|
||||||
|
int EVP_Digest(void *data, unsigned int count,
|
||||||
|
unsigned char *md, unsigned int *size, const EVP_MD *type);
|
||||||
|
|
||||||
int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
|
int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
|
||||||
void EVP_set_pw_prompt(char *prompt);
|
void EVP_set_pw_prompt(char *prompt);
|
||||||
|
@@ -82,7 +82,7 @@ OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer)
|
|||||||
#endif
|
#endif
|
||||||
iname = X509_get_issuer_name(subject);
|
iname = X509_get_issuer_name(subject);
|
||||||
serial = X509_get_serialNumber(subject);
|
serial = X509_get_serialNumber(subject);
|
||||||
ikey = issuer->cert_info->key->public_key;
|
ikey = X509_get0_pubkey_bitstr(issuer);
|
||||||
return OCSP_cert_id_new(dgst, iname, ikey, serial);
|
return OCSP_cert_id_new(dgst, iname, ikey, serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,6 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
|
|||||||
X509_ALGOR *alg;
|
X509_ALGOR *alg;
|
||||||
OCSP_CERTID *cid = NULL;
|
OCSP_CERTID *cid = NULL;
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
|
|
||||||
if (!(cid = OCSP_CERTID_new())) goto err;
|
if (!(cid = OCSP_CERTID_new())) goto err;
|
||||||
|
|
||||||
@@ -116,9 +115,7 @@ OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
|
|||||||
if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
|
if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) goto err;
|
||||||
|
|
||||||
/* Calculate the issuerKey hash, excluding tag and length */
|
/* Calculate the issuerKey hash, excluding tag and length */
|
||||||
EVP_DigestInit(&ctx,dgst);
|
EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst);
|
||||||
EVP_DigestUpdate(&ctx,issuerKey->data, issuerKey->length);
|
|
||||||
EVP_DigestFinal(&ctx,md,&i);
|
|
||||||
|
|
||||||
if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
|
if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) goto err;
|
||||||
|
|
||||||
@@ -186,7 +183,6 @@ OCSP_BASICRESP *OCSP_basic_response_new(int type, X509* cert)
|
|||||||
{
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
OCSP_RESPID *rid;
|
OCSP_RESPID *rid;
|
||||||
ASN1_BIT_STRING *bs;
|
|
||||||
OCSP_BASICRESP *rsp = NULL;
|
OCSP_BASICRESP *rsp = NULL;
|
||||||
unsigned char md[SHA_DIGEST_LENGTH];
|
unsigned char md[SHA_DIGEST_LENGTH];
|
||||||
|
|
||||||
@@ -205,9 +201,7 @@ OCSP_BASICRESP *OCSP_basic_response_new(int type, X509* cert)
|
|||||||
/* SHA-1 hash of responder's public key
|
/* SHA-1 hash of responder's public key
|
||||||
* (excluding the tag and length fields)
|
* (excluding the tag and length fields)
|
||||||
*/
|
*/
|
||||||
bs = cert->cert_info->key->public_key;
|
X509_pubkey_digest(cert, EVP_sha1(), md, NULL);
|
||||||
SHA1(ASN1_STRING_data((ASN1_STRING*)bs),
|
|
||||||
ASN1_STRING_length((ASN1_STRING*)bs), md);
|
|
||||||
if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
|
if (!(rid->value.byKey = ASN1_OCTET_STRING_new()))
|
||||||
goto err;
|
goto err;
|
||||||
if (!(ASN1_OCTET_STRING_set(rid->value.byKey,
|
if (!(ASN1_OCTET_STRING_set(rid->value.byKey,
|
||||||
|
@@ -177,8 +177,6 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
|
unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
|
||||||
ASN1_BIT_STRING *key;
|
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
X509 *x;
|
X509 *x;
|
||||||
|
|
||||||
/* Easy if lookup by name */
|
/* Easy if lookup by name */
|
||||||
@@ -194,10 +192,7 @@ static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
|
|||||||
for (i = 0; i < sk_X509_num(certs); i++)
|
for (i = 0; i < sk_X509_num(certs); i++)
|
||||||
{
|
{
|
||||||
x = sk_X509_value(certs, i);
|
x = sk_X509_value(certs, i);
|
||||||
key = x->cert_info->key->public_key;
|
X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
|
||||||
EVP_DigestInit(&ctx,EVP_sha1());
|
|
||||||
EVP_DigestUpdate(&ctx,key->data, key->length);
|
|
||||||
EVP_DigestFinal(&ctx,tmphash,NULL);
|
|
||||||
if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
|
if(!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
@@ -294,9 +289,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
|
|||||||
if(cid)
|
if(cid)
|
||||||
{
|
{
|
||||||
const EVP_MD *dgst;
|
const EVP_MD *dgst;
|
||||||
EVP_MD_CTX ctx;
|
|
||||||
X509_NAME *iname;
|
X509_NAME *iname;
|
||||||
ASN1_BIT_STRING *ikey;
|
|
||||||
int mdlen;
|
int mdlen;
|
||||||
unsigned char md[EVP_MAX_MD_SIZE];
|
unsigned char md[EVP_MAX_MD_SIZE];
|
||||||
if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm)))
|
if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm)))
|
||||||
@@ -314,11 +307,7 @@ static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
|
|||||||
return -1;
|
return -1;
|
||||||
if (memcmp(md, cid->issuerNameHash->data, mdlen))
|
if (memcmp(md, cid->issuerNameHash->data, mdlen))
|
||||||
return 0;
|
return 0;
|
||||||
ikey = cert->cert_info->key->public_key;
|
X509_pubkey_digest(cert, EVP_sha1(), md, NULL);
|
||||||
|
|
||||||
EVP_DigestInit(&ctx,dgst);
|
|
||||||
EVP_DigestUpdate(&ctx,ikey->data, ikey->length);
|
|
||||||
EVP_DigestFinal(&ctx,md,NULL);
|
|
||||||
if (memcmp(md, cid->issuerKeyHash->data, mdlen))
|
if (memcmp(md, cid->issuerKeyHash->data, mdlen))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@@ -719,6 +719,8 @@ int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
|
|||||||
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
|
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
|
||||||
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
|
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
|
||||||
|
|
||||||
|
int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
|
||||||
|
unsigned char *md, unsigned int *len);
|
||||||
int X509_digest(const X509 *data,const EVP_MD *type,
|
int X509_digest(const X509 *data,const EVP_MD *type,
|
||||||
unsigned char *md, unsigned int *len);
|
unsigned char *md, unsigned int *len);
|
||||||
int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
|
int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
|
||||||
@@ -937,6 +939,7 @@ int X509_set_notBefore(X509 *x, ASN1_TIME *tm);
|
|||||||
int X509_set_notAfter(X509 *x, ASN1_TIME *tm);
|
int X509_set_notAfter(X509 *x, ASN1_TIME *tm);
|
||||||
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
|
int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
|
||||||
EVP_PKEY * X509_get_pubkey(X509 *x);
|
EVP_PKEY * X509_get_pubkey(X509 *x);
|
||||||
|
ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
|
||||||
int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
|
int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
|
||||||
|
|
||||||
int X509_REQ_set_version(X509_REQ *x,long version);
|
int X509_REQ_set_version(X509_REQ *x,long version);
|
||||||
|
@@ -264,6 +264,12 @@ EVP_PKEY *X509_get_pubkey(X509 *x)
|
|||||||
return(X509_PUBKEY_get(x->cert_info->key));
|
return(X509_PUBKEY_get(x->cert_info->key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
|
||||||
|
{
|
||||||
|
if(!x) return NULL;
|
||||||
|
return x->cert_info->key->public_key;
|
||||||
|
}
|
||||||
|
|
||||||
int X509_check_private_key(X509 *x, EVP_PKEY *k)
|
int X509_check_private_key(X509 *x, EVP_PKEY *k)
|
||||||
{
|
{
|
||||||
EVP_PKEY *xk=NULL;
|
EVP_PKEY *xk=NULL;
|
||||||
|
@@ -379,6 +379,15 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne)
|
|||||||
return ASN1_item_dup(&X509_NAME_ENTRY_it, ne);
|
return ASN1_item_dup(&X509_NAME_ENTRY_it, ne);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
|
||||||
|
unsigned int *len)
|
||||||
|
{
|
||||||
|
ASN1_BIT_STRING *key;
|
||||||
|
key = X509_get0_pubkey_bitstr(data);
|
||||||
|
if(!key) return 0;
|
||||||
|
return EVP_Digest(key->data, key->length, md, len, type);
|
||||||
|
}
|
||||||
|
|
||||||
int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
|
int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
|
||||||
unsigned int *len)
|
unsigned int *len)
|
||||||
{
|
{
|
||||||
|
@@ -104,7 +104,6 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
|
|||||||
ASN1_OCTET_STRING *oct;
|
ASN1_OCTET_STRING *oct;
|
||||||
ASN1_BIT_STRING *pk;
|
ASN1_BIT_STRING *pk;
|
||||||
unsigned char pkey_dig[EVP_MAX_MD_SIZE];
|
unsigned char pkey_dig[EVP_MAX_MD_SIZE];
|
||||||
EVP_MD_CTX md;
|
|
||||||
unsigned int diglen;
|
unsigned int diglen;
|
||||||
|
|
||||||
if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
|
if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
|
||||||
@@ -130,9 +129,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_DigestInit(&md, EVP_sha1());
|
EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1());
|
||||||
EVP_DigestUpdate(&md, pk->data, pk->length);
|
|
||||||
EVP_DigestFinal(&md, pkey_dig, &diglen);
|
|
||||||
|
|
||||||
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
|
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
|
||||||
X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
|
X509V3err(X509V3_F_S2I_S2I_SKEY_ID,ERR_R_MALLOC_FAILURE);
|
||||||
|
Reference in New Issue
Block a user