summaryrefslogtreecommitdiffstats
path: root/doc/ssleay.txt
diff options
context:
space:
mode:
authorRalf S. Engelschall <rse@openssl.org>1998-12-30 22:58:47 +0000
committerRalf S. Engelschall <rse@openssl.org>1998-12-30 22:58:47 +0000
commitdb1842132fc4e87cdc006757fbc27dc1c1562337 (patch)
tree3f7223bfd5a090788d8d92bffb14346a3c33dfac /doc/ssleay.txt
parent0c106d75e38032d97d29f864bb772454beb5632f (diff)
Cleanup of doc/ directory: The old/obsolete SSLeay files are now assembled
together in a ssleay.txt file.
Diffstat (limited to 'doc/ssleay.txt')
-rw-r--r--doc/ssleay.txt6607
1 files changed, 6607 insertions, 0 deletions
diff --git a/doc/ssleay.txt b/doc/ssleay.txt
new file mode 100644
index 0000000000..c905f6a0d6
--- /dev/null
+++ b/doc/ssleay.txt
@@ -0,0 +1,6607 @@
+
+Bundle of old SSLeay documentation files [OBSOLETE!]
+
+==== readme ========================================================
+
+This is the old 0.6.6 docuementation. Most of the cipher stuff is still
+relevent but I'm working (very slowly) on new docuemtation.
+The current version can be found online at
+
+http://www.cryptsoft.com/ssleay/doc
+
+==== API.doc ========================================================
+
+SSL - SSLv2/v3/v23 etc.
+
+BIO - methods and how they plug together
+
+MEM - memory allocation callback
+
+CRYPTO - locking for threads
+
+EVP - Ciphers/Digests/signatures
+
+RSA - methods
+
+X509 - certificate retrieval
+
+X509 - validation
+
+X509 - X509v3 extensions
+
+Objects - adding object identifiers
+
+ASN.1 - parsing
+
+PEM - parsing
+
+==== a_verify.doc ========================================================
+
+From eay@mincom.com Fri Oct 4 18:29:06 1996
+Received: by orb.mincom.oz.au id AA29080
+ (5.65c/IDA-1.4.4 for eay); Fri, 4 Oct 1996 08:29:07 +1000
+Date: Fri, 4 Oct 1996 08:29:06 +1000 (EST)
+From: Eric Young <eay@mincom.oz.au>
+X-Sender: eay@orb
+To: wplatzer <wplatzer@iaik.tu-graz.ac.at>
+Cc: Eric Young <eay@mincom.oz.au>, SSL Mailing List <ssl-users@mincom.com>
+Subject: Re: Netscape's Public Key
+In-Reply-To: <19961003134837.NTM0049@iaik.tu-graz.ac.at>
+Message-Id: <Pine.SOL.3.91.961004081346.8018K-100000@orb>
+Mime-Version: 1.0
+Content-Type: TEXT/PLAIN; charset=US-ASCII
+Status: RO
+X-Status:
+
+On Thu, 3 Oct 1996, wplatzer wrote:
+> I get Public Key from Netscape (Gold 3.0b4), but cannot do anything
+> with it... It looks like (asn1parse):
+>
+> 0:d=0 hl=3 l=180 cons: SEQUENCE
+> 3:d=1 hl=2 l= 96 cons: SEQUENCE
+> 5:d=2 hl=2 l= 92 cons: SEQUENCE
+> 7:d=3 hl=2 l= 13 cons: SEQUENCE
+> 9:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
+> 20:d=4 hl=2 l= 0 prim: NULL
+> 22:d=3 hl=2 l= 75 prim: BIT STRING
+> 99:d=2 hl=2 l= 0 prim: IA5STRING :
+> 101:d=1 hl=2 l= 13 cons: SEQUENCE
+> 103:d=2 hl=2 l= 9 prim: OBJECT :md5withRSAEncryption
+> 114:d=2 hl=2 l= 0 prim: NULL
+> 116:d=1 hl=2 l= 65 prim: BIT STRING
+>
+> The first BIT STRING is the public key and the second BIT STRING is
+> the signature.
+> But a public key consists of the public exponent and the modulus. Are
+> both numbers in the first BIT STRING?
+> Is there a document simply describing this coding stuff (checking
+> signature, get the public key, etc.)?
+
+Minimal in SSLeay. If you want to see what the modulus and exponent are,
+try asn1parse -offset 25 -length 75 <key.pem
+asn1parse will currently stuff up on the 'length 75' part (fixed in next
+release) but it will print the stuff. If you are after more
+documentation on ASN.1, have a look at www.rsa.com and get their PKCS
+documents, most of my initial work on SSLeay was done using them.
+
+As for SSLeay,
+util/crypto.num and util/ssl.num are lists of all exported functions in
+the library (but not macros :-(.
+
+The ones for extracting public keys from certificates and certificate
+requests are EVP_PKEY * X509_REQ_extract_key(X509_REQ *req);
+EVP_PKEY * X509_extract_key(X509 *x509);
+
+To verify a signature on a signed ASN.1 object
+int X509_verify(X509 *a,EVP_PKEY *key);
+int X509_REQ_verify(X509_REQ *a,EVP_PKEY *key);
+int X509_CRL_verify(X509_CRL *a,EVP_PKEY *key);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a,EVP_PKEY *key);
+
+I should mention that EVP_PKEY can be used to hold a public or a private key,
+since for things like RSA and DSS, a public key is just a subset of what
+is stored for the private key.
+
+To sign any of the above structures
+
+int X509_sign(X509 *a,EVP_PKEY *key,EVP_MD *md);
+int X509_REQ_sign(X509_REQ *a,EVP_PKEY *key,EVP_MD *md);
+int X509_CRL_sign(X509_CRL *a,EVP_PKEY *key,EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *a,EVP_PKEY *key,EVP_MD *md);
+
+where md is the message digest to sign with.
+
+There are all defined in x509.h and all the _sign and _verify functions are
+actually macros to the ASN1_sign() and ASN1_verify() functions.
+These functions will put the correct algorithm identifiers in the correct
+places in the structures.
+
+eric
+--
+Eric Young | BOOL is tri-state according to Bill Gates.
+AARNet: eay@mincom.oz.au | RTFM Win32 GetMessage().
+
+==== verify ========================================================
+
+X509_verify_cert_chain(
+ CERT_STORE *cert_store,
+ STACK /* X509 */ *certs,
+ int *verify_result,
+ int (*verify_error_callback)()
+ char *argument_to_callback, /* SSL */
+
+app_verify_callback(
+ char *app_verify_arg, /* from SSL_CTX */
+ STACK /* X509 */ *certs,
+ int *verify_result,
+ int (*verify_error_callback)()
+ SSL *s,
+
+int X509_verify_cert(
+ CERT_STORE *cert_store,
+ X509 *x509,
+ int *verify_result,
+ int (*verify_error_callback)(),
+ char *arg,
+
+==== apps.doc ========================================================
+
+The applications
+
+Ok, where to begin....
+In the begining, when SSLeay was small (April 1995), there
+were but few applications, they did happily cohabit in
+the one bin directory. Then over time, they did multiply and grow,
+and they started to look like microsoft software; 500k to print 'hello world'.
+A new approach was needed. They were coalessed into one 'Monolithic'
+application, ssleay. This one program is composed of many programs that
+can all be compiled independantly.
+
+ssleay has 3 modes of operation.
+1) If the ssleay binaray has the name of one of its component programs, it
+executes that program and then exits. This can be achieve by using hard or
+symbolic links, or failing that, just renaming the binary.
+2) If the first argument to ssleay is the name of one of the component
+programs, that program runs that program and then exits.
+3) If there are no arguments, ssleay enters a 'command' mode. Each line is
+interpreted as a program name plus arguments. After each 'program' is run,
+ssleay returns to the comand line.
+
+dgst - message digests
+enc - encryption and base64 encoding
+
+ans1parse - 'pulls' appart ASN.1 encoded objects like certificates.
+
+dh - Diffle-Hellman parameter manipulation.
+rsa - RSA manipulations.
+crl - Certificate revokion list manipulations
+x509 - X509 cert fiddles, including signing.
+pkcs7 - pkcs7 manipulation, only DER versions right now.
+
+genrsa - generate an RSA private key.
+gendh - Generate a set of Diffle-Hellman parameters.
+req - Generate a PKCS#10 object, a certificate request.
+
+s_client - SSL client program
+s_server - SSL server program
+s_time - A SSL protocol timing program
+s_mult - Another SSL server, but it multiplexes
+ connections.
+s_filter - under development
+
+errstr - Convert SSLeay error numbers to strings.
+ca - Sign certificate requests, and generate
+ certificate revokion lists
+crl2pkcs7 - put a crl and certifcates into a pkcs7 object.
+speed - Benchmark the ciphers.
+verify - Check certificates
+hashdir - under development
+
+[ there a now a few more options, play with the program to see what they
+ are ]
+
+==== asn1.doc ========================================================
+
+The ASN.1 Routines.
+
+ASN.1 is a specification for how to encode structured 'data' in binary form.
+The approach I have take to the manipulation of structures and their encoding
+into ASN.1 is as follows.
+
+For each distinct structure there are 4 function of the following form
+TYPE *TYPE_new(void);
+void TYPE_free(TYPE *);
+TYPE *d2i_TYPE(TYPE **a,unsigned char **pp,long length);
+long i2d_TYPE(TYPE *a,unsigned char **pp); /* CHECK RETURN VALUE */
+
+where TYPE is the type of the 'object'. The TYPE that have these functions
+can be in one of 2 forms, either the internal C malloc()ed data structure
+or in the DER (a variant of ASN.1 encoding) binary encoding which is just
+an array of unsigned bytes. The 'i2d' functions converts from the internal
+form to the DER form and the 'd2i' functions convert from the DER form to
+the internal form.
+
+The 'new' function returns a malloc()ed version of the structure with all
+substructures either created or left as NULL pointers. For 'optional'
+fields, they are normally left as NULL to indicate no value. For variable
+size sub structures (often 'SET OF' or 'SEQUENCE OF' in ASN.1 syntax) the
+STACK data type is used to hold the values. Have a read of stack.doc
+and have a look at the relevant header files to see what I mean. If there
+is an error while malloc()ing the structure, NULL is returned.
+
+The 'free' function will free() all the sub components of a particular
+structure. If any of those sub components have been 'removed', replace
+them with NULL pointers, the 'free' functions are tolerant of NULL fields.
+
+The 'd2i' function copies a binary representation into a C structure. It
+operates as follows. 'a' is a pointer to a pointer to
+the structure to populate, 'pp' is a pointer to a pointer to where the DER
+byte string is located and 'length' is the length of the '*pp' data.
+If there are no errors, a pointer to the populated structure is returned.
+If there is an error, NULL is returned. Errors can occur because of
+malloc() failures but normally they will be due to syntax errors in the DER
+encoded data being parsed. It is also an error if there was an
+attempt to read more that 'length' bytes from '*p'. If
+everything works correctly, the value in '*p' is updated
+to point at the location just beyond where the DER
+structure was read from. In this way, chained calls to 'd2i' type
+functions can be made, with the pointer into the 'data' array being
+'walked' along the input byte array.
+Depending on the value passed for 'a', different things will be done. If
+'a' is NULL, a new structure will be malloc()ed and returned. If '*a' is
+NULL, a new structure will be malloc()ed and put into '*a' and returned.
+If '*a' is not NULL, the structure in '*a' will be populated, or in the
+case of an error, free()ed and then returned.
+Having these semantics means that a structure
+can call a 'd2i' function to populate a field and if the field is currently
+NULL, the structure will be created.
+
+The 'i2d' function type is used to copy a C structure to a byte array.
+The parameter 'a' is the structure to convert and '*p' is where to put it.
+As for the 'd2i' type structure, 'p' is updated to point after the last
+byte written. If p is NULL, no data is written. The function also returns
+the number of bytes written. Where this becomes useful is that if the
+function is called with a NULL 'p' value, the length is returned. This can
+then be used to malloc() an array of bytes and then the same function can
+be recalled passing the malloced array to be written to. e.g.
+
+int len;
+unsigned char *bytes,*p;
+len=i2d_X509(x,NULL); /* get the size of the ASN1 encoding of 'x' */
+if ((bytes=(unsigned char *)malloc(len)) == NULL)
+ goto err;
+p=bytes;
+i2d_X509(x,&p);
+
+Please note that a new variable, 'p' was passed to i2d_X509. After the
+call to i2d_X509 p has been incremented by len bytes.
+
+Now the reason for this functional organisation is that it allows nested
+structures to be built up by calling these functions as required. There
+are various macros used to help write the general 'i2d', 'd2i', 'new' and
+'free' functions. They are discussed in another file and would only be
+used by some-one wanting to add new structures to the library. As you
+might be able to guess, the process of writing ASN.1 files can be a bit CPU
+expensive for complex structures. I'm willing to live with this since the
+simpler library code make my life easier and hopefully most programs using
+these routines will have their execution profiles dominated by cipher or
+message digest routines.
+What follows is a list of 'TYPE' values and the corresponding ASN.1
+structure and where it is used.
+
+TYPE ASN.1
+ASN1_INTEGER INTEGER
+ASN1_BIT_STRING BIT STRING
+ASN1_OCTET_STRING OCTET STRING
+ASN1_OBJECT OBJECT IDENTIFIER
+ASN1_PRINTABLESTRING PrintableString
+ASN1_T61STRING T61String
+ASN1_IA5STRING IA5String
+ASN1_UTCTIME UTCTime
+ASN1_TYPE Any of the above mentioned types plus SEQUENCE and SET
+
+Most of the above mentioned types are actualled stored in the
+ASN1_BIT_STRING type and macros are used to differentiate between them.
+The 3 types used are
+
+typedef struct asn1_object_st
+ {
+ /* both null if a dynamic ASN1_OBJECT, one is
+ * defined if a 'static' ASN1_OBJECT */
+ char *sn,*ln;
+ int nid;
+ int length;
+ unsigned char *data;
+ } ASN1_OBJECT;
+This is used to store ASN1 OBJECTS. Read 'objects.doc' for details ono
+routines to manipulate this structure. 'sn' and 'ln' are used to hold text
+strings that represent the object (short name and long or lower case name).
+These are used by the 'OBJ' library. 'nid' is a number used by the OBJ
+library to uniquely identify objects. The ASN1 routines will populate the
+'length' and 'data' fields which will contain the bit string representing
+the object.
+
+typedef struct asn1_bit_string_st
+ {
+ int length;
+ int type;
+ unsigned char *data;
+ } ASN1_BIT_STRING;
+This structure is used to hold all the other base ASN1 types except for
+ASN1_UTCTIME (which is really just a 'char *'). Length is the number of
+bytes held in data and type is the ASN1 type of the object (there is a list
+in asn1.h).
+
+typedef struct asn1_type_st
+ {
+ int type;
+ union {
+ char *ptr;
+ ASN1_INTEGER * integer;
+ ASN1_BIT_STRING * bit_string;
+ ASN1_OCTET_STRING * octet_string;
+ ASN1_OBJECT * object;
+ ASN1_PRINTABLESTRING * printablestring;
+ ASN1_T61STRING * t61string;
+ ASN1_IA5STRING * ia5string;
+ ASN1_UTCTIME * utctime;
+ ASN1_BIT_STRING * set;
+ ASN1_BIT_STRING * sequence;
+ } value;
+ } ASN1_TYPE;
+This structure is used in a few places when 'any' type of object can be
+expected.
+
+X509 Certificate
+X509_CINF CertificateInfo
+X509_ALGOR AlgorithmIdentifier
+X509_NAME Name
+X509_NAME_ENTRY A single sub component of the name.
+X509_VAL Validity
+X509_PUBKEY SubjectPublicKeyInfo
+The above mentioned types are declared in x509.h. They are all quite
+straight forward except for the X509_NAME/X509_NAME_ENTRY pair.
+A X509_NAME is a STACK (see stack.doc) of X509_NAME_ENTRY's.
+typedef struct X509_name_entry_st
+ {
+ ASN1_OBJECT *object;
+ ASN1_BIT_STRING *value;
+ int set;
+ int size; /* temp variable */
+ } X509_NAME_ENTRY;
+The size is a temporary variable used by i2d_NAME and set is the set number
+for the particular NAME_ENTRY. A X509_NAME is encoded as a sequence of
+sequence of sets. Normally each set contains only a single item.
+Sometimes it contains more. Normally throughout this library there will be
+only one item per set. The set field contains the 'set' that this entry is
+a member of. So if you have just created a X509_NAME structure and
+populated it with X509_NAME_ENTRYs, you should then traverse the X509_NAME
+(which is just a STACK) and set the 'set/' field to incrementing numbers.
+For more details on why this is done, read the ASN.1 spec for Distinguished
+Names.
+
+X509_REQ CertificateRequest
+X509_REQ_INFO CertificateRequestInfo
+These are used to hold certificate requests.
+
+X509_CRL CertificateRevocationList
+These are used to hold a certificate revocation list
+
+RSAPrivateKey PrivateKeyInfo
+RSAPublicKey PublicKeyInfo
+Both these 'function groups' operate on 'RSA' structures (see rsa.doc).
+The difference is that the RSAPublicKey operations only manipulate the m
+and e fields in the RSA structure.
+
+DSAPrivateKey DSS private key
+DSAPublicKey DSS public key
+Both these 'function groups' operate on 'DSS' structures (see dsa.doc).
+The difference is that the RSAPublicKey operations only manipulate the
+XXX fields in the DSA structure.
+
+DHparams DHParameter
+This is used to hold the p and g value for The Diffie-Hellman operation.
+The function deal with the 'DH' strucure (see dh.doc).
+
+Now all of these function types can be used with several other functions to give
+quite useful set of general manipulation routines. Normally one would
+not uses these functions directly but use them via macros.
+
+char *ASN1_dup(int (*i2d)(),char *(*d2i)(),char *x);
+'x' is the input structure case to a 'char *', 'i2d' is the 'i2d_TYPE'
+function for the type that 'x' is and d2i is the 'd2i_TYPE' function for the
+type that 'x' is. As is obvious from the parameters, this function
+duplicates the strucutre by transforming it into the DER form and then
+re-loading it into a new strucutre and returning the new strucutre. This
+is obviously a bit cpu intensive but when faced with a complex dynamic
+structure this is the simplest programming approach. There are macros for
+duplicating the major data types but is simple to add extras.
+
+char *ASN1_d2i_fp(char *(*new)(),char *(*d2i)(),FILE *fp,unsigned char **x);
+'x' is a pointer to a pointer of the 'desired type'. new and d2i are the
+corresponding 'TYPE_new' and 'd2i_TYPE' functions for the type and 'fp' is
+an open file pointer to read from. This function reads from 'fp' as much
+data as it can and then uses 'd2i' to parse the bytes to load and return
+the parsed strucutre in 'x' (if it was non-NULL) and to actually return the
+strucutre. The behavior of 'x' is as per all the other d2i functions.
+
+char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
+The 'BIO' is the new IO type being used in SSLeay (see bio.doc). This
+function is the same as ASN1_d2i_fp() except for the BIO argument.
+ASN1_d2i_fp() actually calls this function.
+
+int ASN1_i2d_fp(int (*i2d)(),FILE *out,unsigned char *x);
+'x' is converted to bytes by 'i2d' and then written to 'out'. ASN1_i2d_fp
+and ASN1_d2i_fp are not really symetric since ASN1_i2d_fp will read all
+available data from the file pointer before parsing a single item while
+ASN1_i2d_fp can be used to write a sequence of data objects. To read a
+series of objects from a file I would sugest loading the file into a buffer
+and calling the relevent 'd2i' functions.
+
+char *ASN1_d2i_bio(char *(*new)(),char *(*d2i)(),BIO *fp,unsigned char **x);
+This function is the same as ASN1_i2d_fp() except for the BIO argument.
+ASN1_i2d_fp() actually calls this function.
+
+char * PEM_ASN1_read(char *(*d2i)(),char *name,FILE *fp,char **x,int (*cb)());
+This function will read the next PEM encoded (base64) object of the same
+type as 'x' (loaded by the d2i function). 'name' is the name that is in
+the '-----BEGIN name-----' that designates the start of that object type.
+If the data is encrypted, 'cb' will be called to prompt for a password. If
+it is NULL a default function will be used to prompt from the password.
+'x' is delt with as per the standard 'd2i' function interface. This
+function can be used to read a series of objects from a file. While any
+data type can be encrypted (see PEM_ASN1_write) only RSA private keys tend
+to be encrypted.
+
+char * PEM_ASN1_read_bio(char *(*d2i)(),char *name,BIO *fp,
+ char **x,int (*cb)());
+Same as PEM_ASN1_read() except using a BIO. This is called by
+PEM_ASN1_read().
+
+int PEM_ASN1_write(int (*i2d)(),char *name,FILE *fp,char *x,EVP_CIPHER *enc,
+ unsigned char *kstr,int klen,int (*callback)());
+
+int PEM_ASN1_write_bio(int (*i2d)(),char *name,BIO *fp,
+ char *x,EVP_CIPHER *enc,unsigned char *kstr,int klen,
+ int (*callback)());
+
+int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature, char *data, RSA *rsa, EVP_MD *type);
+int ASN1_verify(int (*i2d)(), X509_ALGOR *algor1,
+ ASN1_BIT_STRING *signature,char *data, RSA *rsa);
+
+int ASN1_BIT_STRING_cmp(ASN1_BIT_STRING *a, ASN1_BIT_STRING *b);
+ASN1_BIT_STRING *ASN1_BIT_STRING_type_new(int type );
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+void ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_dup(ASN1_UTCTIME *a);
+
+ASN1_BIT_STRING *d2i_asn1_print_type(ASN1_BIT_STRING **a,unsigned char **pp,
+ long length,int type);
+
+int i2d_ASN1_SET(STACK *a, unsigned char **pp,
+ int (*func)(), int ex_tag, int ex_class);
+STACK * d2i_ASN1_SET(STACK **a, unsigned char **pp, long length,
+ char *(*func)(), int ex_tag, int ex_class);
+
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *object);
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+
+/* given a string, return the correct type. Max is the maximum number
+ * of bytes to parse. It stops parsing when 'max' bytes have been
+ * processed or a '\0' is hit */
+int ASN1_PRINTABLE_type(unsigned char *s,int max);
+
+void ASN1_parse(BIO *fp,unsigned char *pp,long len);
+
+int i2d_ASN1_bytes(ASN1_BIT_STRING *a, unsigned char **pp, int tag, int class);
+ASN1_BIT_STRING *d2i_ASN1_bytes(ASN1_OCTET_STRING **a, unsigned char **pp,
+ long length, int Ptag, int Pclass);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(unsigned char **pp, long *plength, int *ptag,
+ int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+ int tag, int class);
+int ASN1_object_size(int constructed, int length, int tag);
+
+X509 * X509_get_cert(CERTIFICATE_CTX *ctx,X509_NAME * name,X509 *tmp_x509);
+int X509_add_cert(CERTIFICATE_CTX *ctx,X509 *);
+
+char * X509_cert_verify_error_string(int n);
+int X509_add_cert_file(CERTIFICATE_CTX *c,char *file, int type);
+char * X509_gmtime (char *s, long adj);
+int X509_add_cert_dir (CERTIFICATE_CTX *c,char *dir, int type);
+int X509_load_verify_locations (CERTIFICATE_CTX *ctx,
+ char *file_env, char *dir_env);
+int X509_set_default_verify_paths(CERTIFICATE_CTX *cts);
+X509 * X509_new_D2i_X509(int len, unsigned char *p);
+char * X509_get_default_cert_area(void );
+char * X509_get_default_cert_dir(void );
+char * X509_get_default_cert_file(void );
+char * X509_get_default_cert_dir_env(void );
+char * X509_get_default_cert_file_env(void );
+char * X509_get_default_private_dir(void );
+X509_REQ *X509_X509_TO_req(X509 *x, RSA *rsa);
+int X509_cert_verify(CERTIFICATE_CTX *ctx,X509 *xs, int (*cb)());
+
+CERTIFICATE_CTX *CERTIFICATE_CTX_new();
+void CERTIFICATE_CTX_free(CERTIFICATE_CTX *c);
+
+void X509_NAME_print(BIO *fp, X509_NAME *name, int obase);
+int X509_print_fp(FILE *fp,X509 *x);
+int X509_print(BIO *fp,X509 *x);
+
+X509_INFO * X509_INFO_new(void);
+void X509_INFO_free(X509_INFO *a);
+
+char * X509_NAME_oneline(X509_NAME *a);
+
+#define X509_verify(x,rsa)
+#define X509_REQ_verify(x,rsa)
+#define X509_CRL_verify(x,rsa)
+
+#define X509_sign(x,rsa,md)
+#define X509_REQ_sign(x,rsa,md)
+#define X509_CRL_sign(x,rsa,md)
+
+#define X509_dup(x509)
+#define d2i_X509_fp(fp,x509)
+#define i2d_X509_fp(fp,x509)
+#define d2i_X509_bio(bp,x509)
+#define i2d_X509_bio(bp,x509)
+
+#define X509_CRL_dup(crl)
+#define d2i_X509_CRL_fp(fp,crl)
+#define i2d_X509_CRL_fp(fp,crl)
+#define d2i_X509_CRL_bio(bp,crl)
+#define i2d_X509_CRL_bio(bp,crl)
+
+#define X509_REQ_dup(req)
+#define d2i_X509_REQ_fp(fp,req)
+#define i2d_X509_REQ_fp(fp,req)
+#define d2i_X509_REQ_bio(bp,req)
+#define i2d_X509_REQ_bio(bp,req)
+
+#define RSAPrivateKey_dup(rsa)
+#define d2i_RSAPrivateKey_fp(fp,rsa)
+#define i2d_RSAPrivateKey_fp(fp,rsa)
+#define d2i_RSAPrivateKey_bio(bp,rsa)
+#define i2d_RSAPrivateKey_bio(bp,rsa)
+
+#define X509_NAME_dup(xn)
+#define X509_NAME_ENTRY_dup(ne)
+
+void X509_REQ_print_fp(FILE *fp,X509_REQ *req);
+void X509_REQ_print(BIO *fp,X509_REQ *req);
+
+RSA *X509_REQ_extract_key(X509_REQ *req);
+RSA *X509_extract_key(X509 *x509);
+
+int X509_issuer_and_serial_cmp(X509 *a, X509 *b);
+unsigned long X509_issuer_and_serial_hash(X509 *a);
+
+X509_NAME * X509_get_issuer_name(X509 *a);
+int X509_issuer_name_cmp(X509 *a, X509 *b);
+unsigned long X509_issuer_name_hash(X509 *a);
+
+X509_NAME * X509_get_subject_name(X509 *a);
+int X509_subject_name_cmp(X509 *a,X509 *b);
+unsigned long X509_subject_name_hash(X509 *x);
+
+int X509_NAME_cmp (X509_NAME *a, X509_NAME *b);
+unsigned long X509_NAME_hash(X509_NAME *x);
+
+
+==== bio.doc ========================================================
+
+BIO Routines
+
+This documentation is rather sparse, you are probably best
+off looking at the code for specific details.
+
+The BIO library is a IO abstraction that was originally
+inspired by the need to have callbacks to perform IO to FILE
+pointers when using Windows 3.1 DLLs. There are two types
+of BIO; a source/sink type and a filter type.
+The source/sink methods are as follows:
+- BIO_s_mem() memory buffer - a read/write byte array that
+ grows until memory runs out :-).
+- BIO_s_file() FILE pointer - A wrapper around the normal
+ 'FILE *' commands, good for use with stdin/stdout.
+- BIO_s_fd() File descriptor - A wrapper around file
+ descriptors, often used with pipes.
+- BIO_s_socket() Socket - Used around sockets. It is
+ mostly in the Microsoft world that sockets are different
+ from file descriptors and there are all those ugly winsock
+ commands.
+- BIO_s_null() Null - read nothing and write nothing.; a
+ useful endpoint for filter type BIO's specifically things
+ like the message digest BIO.
+
+The filter types are
+- BIO_f_buffer() IO buffering - does output buffering into
+ larger chunks and performs input buffering to allow gets()
+ type functions.
+- BIO_f_md() Message digest - a transparent filter that can
+ be asked to return a message digest for the data that has
+ passed through it.
+- BIO_f_cipher() Encrypt or decrypt all data passing
+ through the filter.
+- BIO_f_base64() Base64 decode on read and encode on write.
+- BIO_f_ssl() A filter that performs SSL encryption on the
+ data sent through it.
+
+Base BIO functions.
+The BIO library has a set of base functions that are
+implemented for each particular type. Filter BIOs will
+normally call the equivalent function on the source/sink BIO
+that they are layered on top of after they have performed
+some modification to the data stream. Multiple filter BIOs
+can be 'push' into a stack of modifers, so to read from a
+file, unbase64 it, then decrypt it, a BIO_f_cipher,
+BIO_f_base64 and a BIO_s_file would probably be used. If a
+sha-1 and md5 message digest needed to be generated, a stack
+two BIO_f_md() BIOs and a BIO_s_null() BIO could be used.
+The base functions are
+- BIO *BIO_new(BIO_METHOD *type); Create a new BIO of type 'type'.
+- int BIO_free(BIO *a); Free a BIO structure. Depending on
+ the configuration, this will free the underlying data
+ object for a source/sink BIO.
+- int BIO_read(BIO *b, char *data, int len); Read upto 'len'
+ bytes into 'data'.
+- int BIO_gets(BIO *bp,char *buf, int size); Depending on
+ the BIO, this can either be a 'get special' or a get one
+ line of data, as per fgets();
+- int BIO_write(BIO *b, char *data, int len); Write 'len'
+ bytes from 'data' to the 'b' BIO.
+- int BIO_puts(BIO *bp,char *buf); Either a 'put special' or
+ a write null terminated string as per fputs().
+- long BIO_ctrl(BIO *bp,int cmd,long larg,char *parg); A
+ control function which is used to manipulate the BIO
+ structure and modify it's state and or report on it. This
+ function is just about never used directly, rather it
+ should be used in conjunction with BIO_METHOD specific
+ macros.
+- BIO *BIO_push(BIO *new_top, BIO *old); new_top is apped to the
+ top of the 'old' BIO list. new_top should be a filter BIO.
+ All writes will go through 'new_top' first and last on read.
+ 'old' is returned.
+- BIO *BIO_pop(BIO *bio); the new topmost BIO is returned, NULL if
+ there are no more.
+
+If a particular low level BIO method is not supported
+(normally BIO_gets()), -2 will be returned if that method is
+called. Otherwise the IO methods (read, write, gets, puts)
+will return the number of bytes read or written, and 0 or -1
+for error (or end of input). For the -1 case,
+BIO_should_retry(bio) can be called to determine if it was a
+genuine error or a temporary problem. -2 will also be
+returned if the BIO has not been initalised yet, in all
+cases, the correct error codes are set (accessible via the
+ERR library).
+
+
+The following functions are convenience functions:
+- int BIO_printf(BIO *bio, char * format, ..); printf but
+ to a BIO handle.
+- long BIO_ctrl_int(BIO *bp,int cmd,long larg,int iarg); a
+ convenience function to allow a different argument types
+ to be passed to BIO_ctrl().
+- int BIO_dump(BIO *b,char *bytes,int len); output 'len'
+ bytes from 'bytes' in a hex dump debug format.
+- long BIO_debug_callback(BIO *bio, int cmd, char *argp, int
+ argi, long argl, long ret) - a default debug BIO callback,
+ this is mentioned below. To use this one normally has to
+ use the BIO_set_callback_arg() function to assign an
+ output BIO for the callback to use.
+- BIO *BIO_find_type(BIO *bio,int type); when there is a 'stack'
+ of BIOs, this function scan the list and returns the first
+ that is of type 'type', as listed in buffer.h under BIO_TYPE_XXX.
+- void BIO_free_all(BIO *bio); Free the bio and all other BIOs
+ in the list. It walks the bio->next_bio list.
+
+
+
+Extra commands are normally implemented as macros calling BIO_ctrl().
+- BIO_number_read(BIO *bio) - the number of bytes processed
+ by BIO_read(bio,.).
+- BIO_number_written(BIO *bio) - the number of bytes written
+ by BIO_write(bio,.).
+- BIO_reset(BIO *bio) - 'reset' the BIO.
+- BIO_eof(BIO *bio) - non zero if we are at the current end
+ of input.
+- BIO_set_close(BIO *bio, int close_flag) - set the close flag.
+- BIO_get_close(BIO *bio) - return the close flag.
+ BIO_pending(BIO *bio) - return the number of bytes waiting
+ to be read (normally buffered internally).
+- BIO_flush(BIO *bio) - output any data waiting to be output.
+- BIO_should_retry(BIO *io) - after a BIO_read/BIO_write
+ operation returns 0 or -1, a call to this function will
+ return non zero if you should retry the call later (this
+ is for non-blocking IO).
+- BIO_should_read(BIO *io) - we should retry when data can
+ be read.
+- BIO_should_write(BIO *io) - we should retry when data can
+ be written.
+- BIO_method_name(BIO *io) - return a string for the method name.
+- BIO_method_type(BIO *io) - return the unique ID of the BIO method.
+- BIO_set_callback(BIO *io, long (*callback)(BIO *io, int
+ cmd, char *argp, int argi, long argl, long ret); - sets
+ the debug callback.
+- BIO_get_callback(BIO *io) - return the assigned function
+ as mentioned above.
+- BIO_set_callback_arg(BIO *io, char *arg) - assign some
+ data against the BIO. This is normally used by the debug
+ callback but could in reality be used for anything. To
+ get an idea of how all this works, have a look at the code
+ in the default debug callback mentioned above. The
+ callback can modify the return values.
+
+Details of the BIO_METHOD structure.
+typedef struct bio_method_st
+ {
+ int type;
+ char *name;
+ int (*bwrite)();
+ int (*bread)();
+ int (*bputs)();
+ int (*bgets)();
+ long (*ctrl)();
+ int (*create)();
+ int (*destroy)();
+ } BIO_METHOD;
+
+The 'type' is the numeric type of the BIO, these are listed in buffer.h;
+'Name' is a textual representation of the BIO 'type'.
+The 7 function pointers point to the respective function
+methods, some of which can be NULL if not implemented.
+The BIO structure
+typedef struct bio_st
+ {
+ BIO_METHOD *method;
+ long (*callback)(BIO * bio, int mode, char *argp, int
+ argi, long argl, long ret);
+ char *cb_arg; /* first argument for the callback */
+ int init;
+ int shutdown;
+ int flags; /* extra storage */
+ int num;
+ char *ptr;
+ struct bio_st *next_bio; /* used by filter BIOs */
+ int references;
+ unsigned long num_read;
+ unsigned long num_write;
+ } BIO;
+
+- 'Method' is the BIO method.
+- 'callback', when configured, is called before and after
+ each BIO method is called for that particular BIO. This
+ is intended primarily for debugging and of informational feedback.
+- 'init' is 0 when the BIO can be used for operation.
+ Often, after a BIO is created, a number of operations may
+ need to be performed before it is available for use. An
+ example is for BIO_s_sock(). A socket needs to be
+ assigned to the BIO before it can be used.
+- 'shutdown', this flag indicates if the underlying
+ comunication primative being used should be closed/freed
+ when the BIO is closed.
+- 'flags' is used to hold extra state. It is primarily used
+ to hold information about why a non-blocking operation
+ failed and to record startup protocol information for the
+ SSL BIO.
+- 'num' and 'ptr' are used to hold instance specific state
+ like file descriptors or local data structures.
+- 'next_bio' is used by filter BIOs to hold the pointer of the
+ next BIO in the chain. written data is sent to this BIO and
+ data read is taken from it.
+- 'references' is used to indicate the number of pointers to
+ this structure. This needs to be '1' before a call to
+ BIO_free() is made if the BIO_free() function is to
+ actually free() the structure, otherwise the reference
+ count is just decreased. The actual BIO subsystem does
+ not really use this functionality but it is useful when
+ used in more advanced applicaion.
+- num_read and num_write are the total number of bytes
+ read/written via the 'read()' and 'write()' methods.
+
+BIO_ctrl operations.
+The following is the list of standard commands passed as the
+second parameter to BIO_ctrl() and should be supported by
+all BIO as best as possible. Some are optional, some are
+manditory, in any case, where is makes sense, a filter BIO
+should pass such requests to underlying BIO's.
+- BIO_CTRL_RESET - Reset the BIO back to an initial state.
+- BIO_CTRL_EOF - return 0 if we are not at the end of input,
+ non 0 if we are.
+- BIO_CTRL_INFO - BIO specific special command, normal
+ information return.
+- BIO_CTRL_SET - set IO specific parameter.
+- BIO_CTRL_GET - get IO specific parameter.
+- BIO_CTRL_GET_CLOSE - Get the close on BIO_free() flag, one
+ of BIO_CLOSE or BIO_NOCLOSE.
+- BIO_CTRL_SET_CLOSE - Set the close on BIO_free() flag.
+- BIO_CTRL_PENDING - Return the number of bytes available
+ for instant reading
+- BIO_CTRL_FLUSH - Output pending data, return number of bytes output.
+- BIO_CTRL_SHOULD_RETRY - After an IO error (-1 returned)
+ should we 'retry' when IO is possible on the underlying IO object.
+- BIO_CTRL_RETRY_TYPE - What kind of IO are we waiting on.
+
+The following command is a special BIO_s_file() specific option.
+- BIO_CTRL_SET_FILENAME - specify a file to open for IO.
+
+The BIO_CTRL_RETRY_TYPE needs a little more explanation.
+When performing non-blocking IO, or say reading on a memory
+BIO, when no data is present (or cannot be written),
+BIO_read() and/or BIO_write() will return -1.
+BIO_should_retry(bio) will return true if this is due to an
+IO condition rather than an actual error. In the case of
+BIO_s_mem(), a read when there is no data will return -1 and
+a should retry when there is more 'read' data.
+The retry type is deduced from 2 macros
+BIO_should_read(bio) and BIO_should_write(bio).
+Now while it may appear obvious that a BIO_read() failure
+should indicate that a retry should be performed when more
+read data is available, this is often not true when using
+things like an SSL BIO. During the SSL protocol startup
+multiple reads and writes are performed, triggered by any
+SSL_read or SSL_write.
+So to write code that will transparently handle either a
+socket or SSL BIO,
+ i=BIO_read(bio,..)
+ if (I == -1)
+ {
+ if (BIO_should_retry(bio))
+ {
+ if (BIO_should_read(bio))
+ {
+ /* call us again when BIO can be read */
+ }
+ if (BIO_should_write(bio))
+ {
+ /* call us again when BIO can be written */
+ }
+ }
+ }
+
+At this point in time only read and write conditions can be
+used but in the future I can see the situation for other
+conditions, specifically with SSL there could be a condition
+of a X509 certificate lookup taking place and so the non-
+blocking BIO_read would require a retry when the certificate
+lookup subsystem has finished it's lookup. This is all
+makes more sense and is easy to use in a event loop type
+setup.
+When using the SSL BIO, either SSL_read() or SSL_write()s
+can be called during the protocol startup and things will
+still work correctly.
+The nice aspect of the use of the BIO_should_retry() macro
+is that all the errno codes that indicate a non-fatal error
+are encapsulated in one place. The Windows specific error
+codes and WSAGetLastError() calls are also hidden from the
+application.
+<