Cryptography for Developers

At this point, we have all the code we require to implement public key (PK) standards such as PKCS or ANSI X9.62. The first thing we must master is working with SEQUENCEs. No common PK standard will use the ASN.1 types (other than SEQUENCE) directly.
Essentially container ASN.1 type is an array of the asn1_list type. So let us examine how we convert a simple container to code these routines can use.
RSAKey ::= SEQUENCE { N INTEGER, E INTEGER} First, we will begin with defining a list.
asn1_list RSAKey[2];
Next, we need two integers to hold the values. Keep in mind that these are the C long type and not a BigNum as we actually require for secure RSA. This is for demonstration purposes only.
long N, E;
Now we must actually assign the elements of the RSAKey.
RSAKey[0].type = ASN1_DER_INTEGER;<a name="176"></a><a name="IDX-84"></a>RSAKey[0].length = 1;RSAKey[0].data = &N;
This triplet of code is fairly awkward and makes ASN.1 coding a serious pain. A simpler solution to this problem is to define a macro to assign the values in a single line of C.
asn1.h:144 #define asn1_set(list, index, Type, Length, Data) \ 145 do { \ 146 asn1_list *ABC_list; \ 147 int ABC_index; \ 148 \ 149 ABC_list = list; \ 150 ABC_index = index; \ 151 \ 152 ABC_list[ABC_index].type = Type; \ 153 ABC_list[ABC_index].length = Length; \ 154 ABC_list[ABC_index].data = Data; \ 155 } while (0); The macro for those unfamiliar with the C preprocessor looks fairly indirect. First, we make a copy of the list and index parameters. This allows them to be temporal. Consider the invocation as follows.
asn1_set(mylist, i++, type, length, data);
If we did not first make a copy of the index, it would be different in every instance it was used during the macro. Similarly, we could...