On Wed, 8 Apr 1998 [EMAIL PROTECTED] wrote:
> Somewhere within SSLeay is a way to get object IDs. For example, for RSA
> signed MD5 uses the following set of bytes:
> {0x30, 0x20, 0x30, 12, 6, 8,
> 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 2, 5, 5, 0, 4, 16},
> How do I get this stream using an SSLeay call. I know it is somewhere in
> the asn1 and/or objects area, but I don't know where to start.
Glad you asked :-),
SSLeay uses what I call Numeric IDentifiers (or NID) internally for any of the
'interesting' objects. A NID can also have a long (or lower case) string,
a short (or upper case) string and a ANS1_OBJECT structure.
object.h has the predefined entries.
To get the sequence of bytes from a 'NID' or use
ASN1_OBJECT * OBJ_nid2obj(int n);
a string,
int OBJ_txt2nid(char *s); followed by a call to OBJ_nid2obj()
The full set of functions are
ASN1_OBJECT * OBJ_dup(ASN1_OBJECT *o);
ASN1_OBJECT * OBJ_nid2obj(int n);
char * OBJ_nid2ln(int n);
char * OBJ_nid2sn(int n);
int OBJ_obj2nid(ASN1_OBJECT *o);
int OBJ_txt2nid(char *s);
int OBJ_ln2nid(char *s);
int OBJ_sn2nid(char *s);
int OBJ_cmp(ASN1_OBJECT *a,ASN1_OBJECT *b);
Mix and match as desired. If their is no ASN1 string, NULL will be returned.
or NID_undef.
Now as you can imagine, I don't have all the ASN1 objects loaded, so use
int OBJ_new_nid(int num);
int OBJ_add_object(ASN1_OBJECT *obj);
int OBJ_create(char *oid,char *sn,char *ln);
OBJ_new_nid() just allocates a new nid (used internally)
OBJ_add_object() adds a new ASN1_OBJECT, which contains lots of fields to fill
out.
OBJ_create() is about the most usefull function. the oid char * is a text
string of the form "1.34.666.3245" which is converted into the ASN.1 binarary
encoding. The new NID is returned.
int OBJ_create_objects(BIO *in);
This is by far the best function, it reads from a BIO and loads the
listed values in and returns the number of objects loaded.
The format of the data read from the BIO is lines of the following form.
1.34.665.3245 short_name long name which can have spaces
As those of you who have snuffed into BIOs, they can read from a file
descriptor, a file, even a memory array :-). So this is a nice way to load
lots of object identifiers from a file.
Anyway, if you don't know the number, yes the text string to look it up.
Now, back to how to get the ASN.1
You have looked up your favorite ASN1_OBJECT strucutre by text name,
/* These are used internally in the ASN1_OBJECT to keep track of
* whether the names and data need to be free()ed */
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id*/
#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
typedef struct asn1_object_st
{
char *sn,*ln;
int nid;
int length;
unsigned char *data;
int flags; /* Should we free this one */
} ASN1_OBJECT;
Ignore some ofthe OBJECT_FLAGS, they are in a state of flux :-), they
currently are used to stop memory leaks :-).
The entries are what they appear to be except for the 'data' field and the
'length' fields encode that bytes and length of the object. Now I cannot
actually remember if I have this as the data bytes or the data bytes + DER
ASN.1 header encoding, so I will outline the correct way to output ASN.1 :)
Functions that operate on ASN1_OBJECTS include
ASN1_OBJECT * ASN1_OBJECT_new(void );
void ASN1_OBJECT_free(ASN1_OBJECT *a);
int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,unsigned char **pp,
long length);
i2d_ASN1_OBJECT() is the function used by most of the ASN.1 routines (i2d ->
internal to ASN.1 DER encoding).
len=i2d_ASN1_OBJECT(obj,NULL);
/* len is how many bytes the encoding will occupy */
p=buf;
i2d_ASN1_OBJECT(obj,&p);
/* the bytes have now been written to 'buf' and p has been incremented
* to point to the location after the encoded bytes */
Other ASN1_OBJECT functions are
int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
which convert asn ASN.1 object into a "1.34.555" type form or preferable a
text form. It actually just calls the next function.
int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
will convert the object directly into the buffer
int a2d_ASN1_OBJECT(unsigned char *out,int olen, char *buf, int num);
This one converts an ascii number seuqnece '1.3.555' etc into DER encoding
without the header. THis is more of an internal function.
anyway, there is a quick summery of the current SSLeay ASN.1 Object Identifer
stuff. I'm not sure how much of this is in SSLeay 0.8.1, but SSLeay 0.9.0
should be out in a few days, so worst case, you can wait :-).
eric
PS I talk about the ASN1. Object identifier bytes and the DER header
as seperate things because they are. Internally, when stored
in ASN1_STRING or ASN1_OBJECT, the header is missing.
+-------------------------------------------------------------------------+
| Administrative requests should be sent to [EMAIL PROTECTED] |
| List service provided by Open Software Associates, http://www.osa.com/ |
+-------------------------------------------------------------------------+