signature=45daf61b5b0148091099c19a080e3802,SSLeay 0.9.0b docs

If you haven't read through the ASN.1 documentation, you probably

had better do so; this library relies heavily on that code.

Here's the ASN.1 for the certificate itself:

Certificate ::= SEQUENCE {

tbsCertificate TBSCertificate,

signatureAlgorithm AlgorithmIdentifier,

signature BIT STRING }

TBSCertificate ::= SEQUENCE {

version [0] Version DEFAULT v1,

serialNumber CertificateSerialNumber,

signature AlgorithmIdentifier,

issuer Name,

validity Validity,

subject Name,

subjectPublicKeyInfo SubjectPublicKeyInfo,

issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,

-- If present, version shall be v2 or v3

subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,

-- If present, version shall be v2 or v3

extensions [3] Extensions OPTIONAL

-- If present, version shall be v3 -- }

Now let's look at X509 as the library defines it:

typedef struct x509_cinf_st

{

ASN1_INTEGER *version; /* [ 0 ] default of v1 */

ASN1_INTEGER *serialNumber;

X509_ALGOR *signature;

X509_NAME *issuer;

X509_VAL *validity;

X509_NAME *subject;

X509_PUBKEY *key;

ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */

ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */

STACK /* X509_EXTENSION */ *extensions; /* [ 3 ] optional in v3 */

} X509_CINF;

typedef struct x509_st

{

X509_CINF *cert_info;

X509_ALGOR *sig_alg;

ASN1_BIT_STRING *signature;

int valid;

int references;

char *name;

} X509;

Treating the certificate as a more-or-less opaque type,

we have the following operations we can perform on it:

make a new one, free an old one, copy it

X509_new, X509_free, X509_dup

convert it to/from DER-encoded form

i2d_X509, d2i_X509

write it to a file, or read it from a file, either in

DER-encoded form or in human-readable text or in PEM

(base64-encoded) form

d2i_X509_fp, i2d_X509_fp,

d2i_X509_bio, i2d_X509_bio, X509_print_fp, X509_print, PEM_write_bio_X509,

PEM_write_X509, PEM_read_bio_X509, PEM_read_X509

verify it, sign it, get the digest of it,

X509_verify, X509_sign, X509_digest,

If we want to deal with the subfields of the structure instead, we can

retrieve a pointer to any of them

X509_get_version, X509_get_serialNumber, X509_get_notBefore,

X509_get_notAfter, X509_get_issuer_name, X509_get_subject_name

stuff any of them with a value or structure of our choice

X509_set_version, X509_set_serialNumber, X509_set_issuer_name,

X509_set_subject_name, X509_set_notBefore, X509_set_notAfter

compare subfields of two of them

X509_issuer_and_serial_cmp, X509_issuer_name_cmp, X509_subject_name_cmp

We also have a few functions that deal with verifying this certificate

against some internal list we have, either by creating a key

by which it can be indexed in our list, or trying to retrieve

it from our list

X509_issuer_and_serial_hash, X509_issuer_name_hash, X509_subject_name_hash,

X509_find_by_issuer_and_serial, X509_find_by_subject

There is also a collection of functions that deal with

X.509v3 extensions, determining how many there are, which

ones are critical, what each one actually it, adding them and deleting

them to the cerificate

X509_get_ext_count, X509_get_ext_by_NID, X509_get_ext_by_OBJ,

X509_get_ext_by_critical, X509_get_ext, X509_delete_ext, X509_add_ext

And finally there is a collection of routines that deal with the public

or private key associated with the certificate on a more detailed

level

X509_extract_key (=X509_get_pubkey), X509_get_pubkey,

X509_set_pubkey, X509_check_private_key

and a couple of routines that get other detailed information about the

certificate by prying it out of complex substructures:

X509_get_signature_type, X509_certificate_type

We'll look at each of these in turn.

X509_new

creates a new X509 structure and returns a pointer to it; if

memory cannot be allocated it returns NULL.

X509_free

frees the memory of the X509 structure pointed

to by x, unless the argument is NULL, in which case

it does nothing.

X509_dup is actually a macro:

#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509,

(char *(*)())d2i_X509,(char *)x509)

It makes a copy of the X509 structure that x points to and returns

it, or NULL on error.

i2d_X509

converts an X.509 structure pointed to by a to DER-encoded form;

it places the results in *pp and then increments *pp to

point to the end of the byte string it has just written, so you

can call several i2d functions in a row. It returns the number of bytes

written to the string or 0 on error.

d2i_X509

converts length bytes of the

DER-encoded string in *pp to an X509 structure, updates *pp

to point to the next byte to be processed, places the new X509 structure

in *a, and returns it, or NULL on error.

The following macros are provided for the convenience of the user:

#define d2i_X509_fp(fp,x509)

(X509 *)ASN1_d2i_fp((char *(*)())X509_new,

(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))

#define i2d_X509_fp(fp,x509)

ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)

#define d2i_X509_bio(bp,x509)

(X509 *)ASN1_d2i_bio((char *(*)())X509_new,

(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))

#define i2d_X509_bio(bp,x509)

ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)

d2i_X509_fp

reads from fp as much

data as it can, in DER-encoded form, and then uses d2i_X509 to

translate that into an X509 structure, which is placed in x509

if that argument is not NULL, or into a newly malloced

structure otherwise. A pointer to the populated structure

is returned, or NULL on error.

i2d_X509_fp

converts the X509 structure pointed to by x509 to DER-encoded

form and writes it out to the file pointer fp.

It returns 1 on success and 0 on error.

d2i_X509_bio

does exactly what d2i_X509_fp does, except that it reads from a

BIO instead of a file pointer.

i2d_X509_bio

does exactly what i2d_X509_fp does, except that it writes to a

BIO instead of a file pointer.

X509_print_fp

translates the X509 structure x into human-readable format

and writes the result to the file pointer fp.

It returns 1 on success or 0 on error.

It uses a fixed format to display the certificate

information. An example is below:

Certificate:

Data:

Version: 1 (0x0)

Serial Number: 0 (0x0)

Signature Algorithm: md5WithRSAEncryption

Issuer: C=AU, ST=Queensland, O=CryptSoft Pty Ltd, CN=Test CA (1024 bit)

Validity

Not Before: Jun 9 13:57:46 1997 GMT

Not After : Jun 9 13:57:46 1998 GMT

Subject: C=AU, ST=Queensland, O=CryptSoft Pty Ltd, CN=Server test cert (512 bit)

Subject Public Key Info:

Public Key Algorithm: rsaEncryption

RSA Public Key: (512 bit)

Modulus (512 bit):

00:9f:b3:c3:84:27:95:ff:12:31:52:0f:15:ef:46:

11:c4:ad:80:e6:36:5b:0f:dd:80:d7:61:8d:e0:fc:

72:45:09:34:fe:55:66:45:43:4c:68:97:6a:fe:a8:

a0:a5:df:5f:78:ff:ee:d7:64:b8:3f:04:cb:6f:ff:

2a:fe:fe:b9:ed

Exponent: 65537 (0x10001)

Signature Algorithm: md5WithRSAEncryption

78:4c:c4:76:0a:f6:9c:28:4f:70:02:cb:bd:8f:20:97:f1:88:

96:9a:00:8c:f9:8a:0f:ea:4b:78:66:48:f6:cf:92:11:7e:6e:

d6:af:27:0a:b2:7a:67:39:1f:ad:19:ea:80:8e:40:9e:67:af:

f7:ea:8f:65:f7:54:6f:3e:73:75:54:9f:e2:c5:0b:f6:75:fd:

0a:15:e3:2b:d3:42:24:0d:d4:cd:01:d2:16:a8:59:12:b1:94:

c0:63:64:00:76:07:a7:6f:b3:01:d6:3a:1e:8e:ab:98:cc:ed:

83:40:83:bb:fb:0a:47:8a:b3:9b:a4:44:b1:01:92:f2:48:29:

8f:3e

X509_print

does exactly the same thing as X509_print_fp, except that

it writes to a BIO instead of a file pointer.

The following macros are provided for the convenience of the user:

#define PEM_write_X509(fp,x)

PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp,(char *)x, NULL,NULL,0,NULL)

#define PEM_write_bio_X509(bp,x)

PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp,(char *)x, NULL,NULL,0,NULL)

#define PEM_read_bio_X509(bp,x,cb)

(X509 *)PEM_ASN1_read_bio((char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb)

#define PEM_read_X509(fp,x,cb)

(X509 *)PEM_ASN1_read((char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb)

PEM_write_X509

converts the X509 structure pointed to by x to DER-encoded form.

The data is then base64-encoded

and written out to fp with BEGIN CERTIFICATE and END headers

around it. 1 is returned on success, or 0 on error.

PEM_write_bio_X509

does the same thing as PEM_write_X509 except that it uses a BIO

instead of a FILE.

PEM_read_X509

reads a PEM-encoded X509 certificate

from the file fp using PEM_read;

calls PEM_get_EVP_CIPHER_INFO to process any DEK-Info header

that might be present, in particular determining the cipher

that was used to encrypt the message body and retrieving the

ivec from the header; calls PEM_do_header to decrypt the

message body if it was encrypted (see the description of that function

in PEM library routines for details

about how a pass phrase (key string) is retrieved from the user, using

the callback cb,

or retrieved from somewhere else); and then

converts it to an X509 structure and places the result in x.

It then returns a pointer to that structure, or NULL on error.

The file must contain a BEGIN CERTIFICATE header or it will not be

parsed properly.

Note that since this function calls PEM_get_EVP_CIPHER_INFO,

the appropriate cipher type (according to the name that is

present in the PEM header) must be loaded into the static cipher and possibly

static alias stack in order for the function to succeed;

EVP cipher/digest lookup routines

for more on this. Ordinaily this will not be a problem, since the

certificate will not have been written out in encrypted form.

This function can be used to read a list of certificates from a file.

PEM_read_bio_X509

does the same thing as PEM_X509_read but uses a BIO instead of a

file pointer.

The following macros are provided for the convenience of the user:

#define X509_verify(a,r)

ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,a->signature,(char *)a->cert_info,r)

#define X509_sign(x,pkey,md)

ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature,

x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)

#define X509_digest(data,type,md,len)

ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)

X509_verify

converts the X509 structure a to DER-encoded form;

computes the message digest of it,

using a->sig_alg as the message digest algorithm;

signs it using r as the key for signing; and finally compares

the results against a->signature. 1 is returned if they

match, 0 on failure or error.

This function actually just calls ASN1_verify,

which calls EVP_VerifyInit, EVP_VerifyUpdate,

and EVP_VerifyFinal;

see

EVP digest handling, signing, verification

if you want details on these functions.

NOTE: this routine calls the dreaded EVP_get_digestbyname()

which means that the static digest and alias stacks must be

initialized; see EVP cipher/digest lookup routines

for more on this.

X509_sign

sets both x->cert_info->signature and x->sig_alg to hold

the appropriate information for the algorithm md->pkey_type,

which might be for example NID_shaWithRSAEncryption.

Then it converts x->cert_info to DER-encoded form,

uses the digest algorithm specified by type

to compute a message digest of the DER-encoded string and uses

the pkey to sign it. The result is placed in

x->signature->data

with the length in x->signature->length.

That same length is returned to the caller, or 0 on error.

This function actually just calls ASN1_sign, which

calls EVP_SignInit, EVP_SignUpdate, and EVP_SignFinal;

see

EVP digest handling, signing, verification

if you want details on these functions.

X509_digest

converts the X509 structure a to DER-encoded form;

computes the message digest of it,

using as the message digest algorithm;

and returns the results in md, with the length

of the returned digest in len.

1 is returned on success, or 0 on error.

This function actually just calls ASN1_digest, which calls

EVP_DigestInit, EVP_DigestUpdate, and EVP_DigestFinal;

see

EVP digest handling, signing, verification

if you want details on these functions.

The following macros are provided for the convenience of the user:

#define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)

#define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)

#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)

X509_get_version

translates the ASN1_INTEGER version

subfield of the certificate pointed to

by x, to a long and returns it.

X509_get_notBefore

returns a pointer to the notBefore

subfield of the certificate pointed to

by x.

X509_get_notAfter

returns a pointer to the notAfter subfield of the certificate pointed to

by x.

X509_get_issuer_name

returns a pointer to the issuer subfield of the certificate pointed to

by a.

X509_get_subject_name

returns a pointer to the subject subfield of the certificate pointed to

by a.

X509_set_version

translates the long version to an ASN1_INTEGER and stuffs it

into the version subfield of the certificate pointed to by x.

It returns 1 on success or 0 on error.

X509_set_serialNumber

makes a copy of the ASN1_INTEGER pointed to by serial and

stuffs it into the serialNumber subfield of the certificate

pointed to by x.

It returns 1 on success or 0 on error.

X509_set_issuer_name

copies the X509_NAME pointed to by name into the

issuer subfield of the certificate pointed to by x.

It returns 1 on success or 0 on error.

X509_set_subject_name

copies the X509_NAME pointed to by name into the

subject subfield of the certificate pointed to by x.

It returns 1 on success or 0 on error.

X509_set_notBefore

copies the ASN1_UTCTIME structure pointed to by tm into the

notBefore subfield of the certificate pointed to by x.

It returns 1 on success or 0 on error.

X509_set_notAfter

copies the ASN1_UTCTIME structure pointed to by tm into the

notAfter subfield of the certificate pointed to by x.

It returns 1 on success or 0 on error.

X509_issuer_and_serial_cmp

returns an integer less than, equal to, or greater than zero,

depending on whether the serial number and issuer of a

are less than, equal to, or greater than the serial number

and issuer of b. The serial numbers are checked first and

only if those match are the issuers checked.

X509_issuer_name_cmp

returns an integer less than, equal to, or greater than zero,

depending on whether the issuer of a

is less than, equal to, or greater than the

issuer of b.

X509_subject_name_cmp

returns an integer less than, equal to, or greater than zero,

depending on whether the subject of a

is less than, equal to, or greater than the

issuer of b.

X509_issuer_and_serial_hash

stuffs the X509_NAME issuer into one printable line

and then computes the MD5 hash of it concatenated with the

ASN1_INTEGER form of the serial number of a.

It returns the first four bytes of the hash in an unsigned long.

This function is used in the library's routines which retrieve

a certificate from a directory.

X509_issuer_name_hash

converts the issuer name into DER-encoded form, applies an MD5 hash,

and returns an unsigned long with the first four bytes of the hash.

X509_subject_name_hash

converts the subject name into DER-encoded form, applies an MD5 hash,

and returns an unsigned long with the first four bytes of the hash.

X509_find_by_issuer_and_serial

searches the passed STACK sk of X509

structures and returns

a pointer to the first one which has the same issuer and serial number

as name and serial. If none do, NULL is returned.

This function calls

X509_issuer_and_serial_cmp.

X509_find_by_subject

searches the passed STACK sk of X509

structures and returns

a pointer to the first one which has the same subject

as name. If none do, NULL is returned.

This function calls

X509_NAME_cmp.

The following functions all rely on X509v3_* functions that manipulate

extenstions;

see X.509 Extension Handling for details on these.

X509_get_ext_count

just calls X509v3_get_ext_count

on the extenstions subfield of x.

X509_get_ext_by_NID

just calls X509v3_get_ext_by_NID

on the extension subfield of x,

passing the other arguments through unchanged.

X509_get_ext_by_OBJ

just calls X509v3_get_ext_by_OBJ on the extension subfield of x,

passing the other arguments through unchanged.

X509_get_ext_by_critical

just calls X509v3_get_ext_by_critical

on the extension subfield of x,

passing the other arguments through unchanged.

X509_get_ext

just calls X509v3_get_ext on the extension subfield of x,

passing the other argument through unchanged.

X509_delete_ext

just calls X509v3_delete_ext on the extension subfield of x,

passing the other argument through unchanged.

X509_add_ext

just calls X509v3_add_ext on the extension subfield of x,

passing the other arguments through unchanged.

The following functions all manipulate keys associated

with an X509 certificate. See X.509 Certificate Subfields Handling for more details on the functions

they call.

The following macro is provided for the convenience of the user:

#define X509_extract_key(x) X509_get_pubkey(x) /*****/

X509_get_pubkey

calls X509_PUBKEY_get on x->cert_info->key to extract

the public key from the certificate and turn it into

an EVP_PKEY

which can be used for encryption with EVP routines.

See Overview of EVP interfaces

for a discussion of the EVP library.

The EVP_PKEY structure is cached in the X509

structure for later use as well.

If this function is called again, a pointer to the cached copy is

used rather than doing the conversion again.

It returns a pointer to the EVP_PKEY or NULL on error.

X509_set_pubkey

calls X509_PUBKEY_set to

convert the EVP_PKEY structure pointed to by

pkey to DER-encoded form and stuff it and its various subfields

into

x->cert_info->key as appropriate.

It returns 1 on success and 0 on error.

X509_check_private_key

checks to see if the private key stored in

pkey is the same as that stored in key xk->pkey;

if it is, 1 is returned, else 0 is returned.

Note that this function always fails if a DH key is passed in pkey.

This function is called indirectly by SSL_use_RSAPrivateKey.

The following macro is provided for the convenience of the user:

#define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))

This just translates the x->sig_alg->algorithm field to a NID.

See EVP public/private key handling

for more on the function it invokes.

X509_certificate_type

returns a collection of flags that describe the kind of key pubkey is

and what it

can be used for. It also calls X509_get_signature_type

on x and adds that information to the flags. Types include:

EVP_PK_RSA RSA key

EVP_PK_DSA DSA key

EVP_PK_DH DH key

EVP_PKT_SIGN key used for signing

EVP_PKT_ENC key used for encryption

EVP_PKT_EXCH key used for (symmetric) key exchange

EVP_PKS_RSA signature done with RSA

EVP_PKS_DSA signature done with DSA

EVP_PKT_EXP key is <= 512 bits long (exportable)

If pubkey is NULL, x->pkey will be transformed into an EVP_PKEY

and that will be used instead.

X509_CINF_new

creates a new X509_CINF structure

and returns a pointer to it; if

memory cannot be allocated it returns NULL.

X509_CINF_free

frees the memory of a

unless the argument is NULL, in which case

it does nothing.

int i2d_X509_CINF(a, pp)

converts an X509_CINF structure

pointed to by a to DER-encoded form;

it places the results in *pp and then increments *pp to

point to the end of the byte string it has just written, so you

can call several i2d functions in a row. It returns the number of bytes

written to the string or 0 on error.

d2i_X509_CINF

converts length bytes of the

DER-encoded string in *pp to an X509_CINF structure,

updates *pp

to point to the next byte to be processed, places a pointer to

the new structure

in a, and returns it, or NULL on error.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值