Check-in [f89918d4df]
Overview
Comment:Added function to convert X.509 DN to string representation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f89918d4dfd6a3166523ef8f49c5d5bf68ebcf1f
User & Date: rkeene on 2010-05-14 20:49:59
Other Links: manifest | tags
Context
2010-05-14
20:50
Added support for reading label from CAC as string check-in: 2f0a97a3f1 user: rkeene tags: trunk
20:49
Added function to convert X.509 DN to string representation check-in: f89918d4df user: rkeene tags: trunk
06:08
Updated to decompress certificates

Updated to correctly process TLV elements -- fixes bug where iterated past them when processing

Updated to correclty process TLV element total length check-in: b9e3c7741b user: rkeene tags: trunk

Changes

Modified asn1-x509.c from [330bebdc8e] to [cf76aee3de].

    12     12   #endif
    13     13   #ifdef HAVE_STDLIB_H
    14     14   #  include <stdlib.h>
    15     15   #endif
    16     16   #ifdef HAVE_STDARG_H
    17     17   #  include <stdarg.h>
    18     18   #endif
           19  +#ifdef HAVE_STDIO_H
           20  +#  include <stdio.h>
           21  +#endif
           22  +#ifdef HAVE_STRING_H
           23  +#  include <string.h>
           24  +#endif
    19     25   
    20     26   #include "asn1-x509.h"
    21     27   
    22     28   struct asn1_object {
    23     29   	unsigned long tag;
    24     30   	unsigned long size;
    25     31   	void *contents;
................................................................................
   179    185   
   180    186   	if (outbuf) {
   181    187   		*outbuf = x509.serial_number.asn1rep;
   182    188   	}
   183    189   
   184    190   	return(x509.serial_number.asn1rep_len);
   185    191   }
          192  +
          193  +/*
          194  + * http://www.blackberry.com/developers/docs/4.6.0api/javax/microedition/pki/Certificate.html
          195  + */
          196  +static const char *_x509_objectid_to_label_string(void *buf, size_t buflen) {
          197  +	switch (buflen) {
          198  +		case 3:
          199  +			if (memcmp(buf, "\x55\x04\x03", 3) == 0) {
          200  +				return("CN");
          201  +			}
          202  +			if (memcmp(buf, "\x55\x04\x04", 3) == 0) {
          203  +				return("SN");
          204  +			}
          205  +			if (memcmp(buf, "\x55\x04\x06", 3) == 0) {
          206  +				return("C");
          207  +			}
          208  +			if (memcmp(buf, "\x55\x04\x07", 3) == 0) {
          209  +				return("L");
          210  +			}
          211  +			if (memcmp(buf, "\x55\x04\x08", 3) == 0) {
          212  +				return("ST");
          213  +			}
          214  +			if (memcmp(buf, "\x55\x04\x09", 3) == 0) {
          215  +				return("STREET");
          216  +			}
          217  +			if (memcmp(buf, "\x55\x04\x0A", 3) == 0) {
          218  +				return("O");
          219  +			}
          220  +			if (memcmp(buf, "\x55\x04\x0B", 3) == 0) {
          221  +				return("OU");
          222  +			}
          223  +			break;
          224  +		case 9:
          225  +			if (memcmp(buf, "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01", 9) == 0) {
          226  +				return("EmailAddress");
          227  +			}
          228  +			break;
          229  +	}
          230  +
          231  +	return("???");
          232  +}
          233  +
          234  +ssize_t x509_dn_to_string(void *asn1_der_buf, size_t asn1_der_buf_len, char *outbuf, size_t outbuf_len, char *matchlabel) {
          235  +	struct asn1_object whole_thing, current_set, current_seq;
          236  +	struct asn1_object label, value;
          237  +	const char *label_str;
          238  +	ssize_t snprintf_ret, retval;
          239  +	char *outbuf_s;
          240  +	int read_ret;
          241  +	int offset;
          242  +
          243  +	if (outbuf == NULL) {
          244  +		return(-1);
          245  +	}
          246  +
          247  +	if (outbuf_len == 0 || asn1_der_buf_len == 0 || asn1_der_buf == NULL) {
          248  +		return(0);
          249  +	}
          250  +
          251  +	read_ret = asn1_x509_read_asn1_object(asn1_der_buf, asn1_der_buf_len, &whole_thing, NULL);
          252  +	if (read_ret != 0) {
          253  +		return(-1);
          254  +	}
          255  +
          256  +	/* Terminate string, in case no valid elements are found we still return a valid string */
          257  +	*outbuf = '\0';
          258  +	outbuf_s = outbuf;
          259  +
          260  +	offset = 0;
          261  +	while (1) {
          262  +		read_ret = asn1_x509_read_asn1_object(whole_thing.contents + offset, whole_thing.size - offset, &current_set, NULL);
          263  +		if (read_ret != 0) {
          264  +			break;
          265  +		}
          266  +
          267  +		offset += current_set.size + 2;
          268  +
          269  +		read_ret = asn1_x509_read_asn1_object(current_set.contents, current_set.size, &current_seq, NULL);
          270  +		if (read_ret != 0) {
          271  +			break;
          272  +		}
          273  +
          274  +		read_ret = asn1_x509_read_asn1_object(current_seq.contents, current_seq.size, &label, &value, NULL);
          275  +
          276  +		label_str = _x509_objectid_to_label_string(label.contents, label.size);
          277  +
          278  +		/* If the user requested only certain labels, exclude others */
          279  +		if (matchlabel) {
          280  +			if (strcmp(matchlabel, label_str) != 0) {
          281  +				continue;
          282  +			}
          283  +		}
          284  +
          285  +		/* If the user requested only certain labels, don't include them in the reply */
          286  +		if (matchlabel) {
          287  +			snprintf_ret = snprintf(outbuf, outbuf_len, "%.*s, ", (unsigned int) value.size, (char *) value.contents);
          288  +		} else {
          289  +			snprintf_ret = snprintf(outbuf, outbuf_len, "%s=%.*s, ", label_str, (unsigned int) value.size, (char *) value.contents);
          290  +		}
          291  +		if (snprintf_ret < 0) {
          292  +			break;
          293  +		}
          294  +
          295  +		if (snprintf_ret > outbuf_len) {
          296  +			snprintf_ret = outbuf_len;
          297  +		}
          298  +
          299  +		outbuf += snprintf_ret;
          300  +		outbuf_len -= snprintf_ret;
          301  +
          302  +		if (outbuf_len < 2) {
          303  +			break;
          304  +		}
          305  +	}
          306  +
          307  +	retval = outbuf - outbuf_s;
          308  +
          309  +	/* Remove trailing ", " added by cumulative process, if found. */
          310  +	if (retval > 2) {
          311  +		if (outbuf_s[retval - 2] == ',') {
          312  +			outbuf_s[retval - 2] = '\0';
          313  +			retval -= 2;
          314  +		}
          315  +	}
          316  +
          317  +	return(retval);
          318  +}

Modified asn1-x509.h from [e7b70ba4d4] to [73df2a78e9].

    11     11   #endif
    12     12   
    13     13   ssize_t x509_to_subject(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
    14     14   
    15     15   ssize_t x509_to_issuer(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
    16     16   
    17     17   ssize_t x509_to_serial(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
           18  +
           19  +ssize_t x509_dn_to_string(void *asn1_der_buf, size_t asn1_der_buf_len, char *outbuf, size_t outbuf_len, char *matchlabel);
    18     20   
    19     21   #endif