plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

decodepem.c (1828B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <mp.h>
      4 #include <libsec.h>
      5 
      6 #define STRLEN(s)	(sizeof(s)-1)
      7 
      8 uchar*
      9 decodepem(char *s, char *type, int *len, char **news)
     10 {
     11 	uchar *d;
     12 	char *t, *e, *tt;
     13 	int n;
     14 
     15 	*len = 0;
     16 
     17 	/*
     18 	 * find the correct section of the file, stripping garbage at the beginning and end.
     19 	 * the data is delimited by -----BEGIN <type>-----\n and -----END <type>-----\n
     20 	 */
     21 	n = strlen(type);
     22 	e = strchr(s, '\0');
     23 	for(t = s; t != nil && t < e; ){
     24 		tt = t;
     25 		t = strchr(tt, '\n');
     26 		if(t != nil)
     27 			t++;
     28 		if(strncmp(tt, "-----BEGIN ", STRLEN("-----BEGIN ")) == 0
     29 		&& strncmp(&tt[STRLEN("-----BEGIN ")], type, n) == 0
     30 		&& strncmp(&tt[STRLEN("-----BEGIN ")+n], "-----\n", STRLEN("-----\n")) == 0)
     31 			break;
     32 	}
     33 	for(tt = t; tt != nil && tt < e; tt++){
     34 		if(strncmp(tt, "-----END ", STRLEN("-----END ")) == 0
     35 		&& strncmp(&tt[STRLEN("-----END ")], type, n) == 0
     36 		&& strncmp(&tt[STRLEN("-----END ")+n], "-----\n", STRLEN("-----\n")) == 0)
     37 			break;
     38 		tt = strchr(tt, '\n');
     39 		if(tt == nil)
     40 			break;
     41 	}
     42 	if(tt == nil || tt == e){
     43 		werrstr("incorrect .pem file format: bad header or trailer");
     44 		return nil;
     45 	}
     46 
     47 	if(news)
     48 		*news = tt+1;
     49 	n = ((tt - t) * 6 + 7) / 8;
     50 	d = malloc(n);
     51 	if(d == nil){
     52 		werrstr("out of memory");
     53 		return nil;
     54 	}
     55 	n = dec64(d, n, t, tt - t);
     56 	if(n < 0){
     57 		free(d);
     58 		werrstr("incorrect .pem file format: bad base64 encoded data");
     59 		return nil;
     60 	}
     61 	*len = n;
     62 	return d;
     63 }
     64 
     65 PEMChain*
     66 decodepemchain(char *s, char *type)
     67 {
     68 	PEMChain *first = nil, *last = nil, *chp;
     69 	uchar *d;
     70 	char *e;
     71 	int n;
     72 
     73 	e = strchr(s, '\0');
     74 	while (s < e) {
     75 		d = decodepem(s, type, &n, &s);
     76 		if(d == nil)
     77 			break;
     78 		chp = malloc(sizeof(PEMChain));
     79 		chp->next = nil;
     80 		chp->pem = d;
     81 		chp->pemlen = n;
     82 		if (first == nil)
     83 			first = chp;
     84 		else
     85 			last->next = chp;
     86 		last = chp;
     87 	}
     88 	return first;
     89 }