xref: /plan9/sys/src/cmd/unix/drawterm/libsec/decodepem.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <mp.h>
4*8ccd4a63SDavid du Colombier #include <libsec.h>
5*8ccd4a63SDavid du Colombier 
6*8ccd4a63SDavid du Colombier #define STRLEN(s)	(sizeof(s)-1)
7*8ccd4a63SDavid du Colombier 
8*8ccd4a63SDavid du Colombier uchar*
decodepem(char * s,char * type,int * len)9*8ccd4a63SDavid du Colombier decodepem(char *s, char *type, int *len)
10*8ccd4a63SDavid du Colombier {
11*8ccd4a63SDavid du Colombier 	uchar *d;
12*8ccd4a63SDavid du Colombier 	char *t, *e, *tt;
13*8ccd4a63SDavid du Colombier 	int n;
14*8ccd4a63SDavid du Colombier 
15*8ccd4a63SDavid du Colombier 	/*
16*8ccd4a63SDavid du Colombier 	 * find the correct section of the file, stripping garbage at the beginning and end.
17*8ccd4a63SDavid du Colombier 	 * the data is delimited by -----BEGIN <type>-----\n and -----END <type>-----\n
18*8ccd4a63SDavid du Colombier 	 */
19*8ccd4a63SDavid du Colombier 	n = strlen(type);
20*8ccd4a63SDavid du Colombier 	e = strchr(s, '\0');
21*8ccd4a63SDavid du Colombier 	for(t = s; t != nil && t < e; ){
22*8ccd4a63SDavid du Colombier 		tt = t;
23*8ccd4a63SDavid du Colombier 		t = strchr(tt, '\n');
24*8ccd4a63SDavid du Colombier 		if(t != nil)
25*8ccd4a63SDavid du Colombier 			t++;
26*8ccd4a63SDavid du Colombier 		if(strncmp(tt, "-----BEGIN ", STRLEN("-----BEGIN ")) == 0
27*8ccd4a63SDavid du Colombier 		&& strncmp(&tt[STRLEN("-----BEGIN ")], type, n) == 0
28*8ccd4a63SDavid du Colombier 		&& strncmp(&tt[STRLEN("-----BEGIN ")+n], "-----\n", STRLEN("-----\n")) == 0)
29*8ccd4a63SDavid du Colombier 			break;
30*8ccd4a63SDavid du Colombier 	}
31*8ccd4a63SDavid du Colombier 	for(tt = t; tt != nil && tt < e; tt++){
32*8ccd4a63SDavid du Colombier 		if(strncmp(tt, "-----END ", STRLEN("-----END ")) == 0
33*8ccd4a63SDavid du Colombier 		&& strncmp(&tt[STRLEN("-----END ")], type, n) == 0
34*8ccd4a63SDavid du Colombier 		&& strncmp(&tt[STRLEN("-----END ")+n], "-----\n", STRLEN("-----\n")) == 0)
35*8ccd4a63SDavid du Colombier 			break;
36*8ccd4a63SDavid du Colombier 		tt = strchr(tt, '\n');
37*8ccd4a63SDavid du Colombier 		if(tt == nil)
38*8ccd4a63SDavid du Colombier 			break;
39*8ccd4a63SDavid du Colombier 	}
40*8ccd4a63SDavid du Colombier 	if(tt == nil || tt == e){
41*8ccd4a63SDavid du Colombier 		werrstr("incorrect .pem file format: bad header or trailer");
42*8ccd4a63SDavid du Colombier 		return nil;
43*8ccd4a63SDavid du Colombier 	}
44*8ccd4a63SDavid du Colombier 
45*8ccd4a63SDavid du Colombier 	n = ((tt - t) * 6 + 7) / 8;
46*8ccd4a63SDavid du Colombier 	d = malloc(n);
47*8ccd4a63SDavid du Colombier 	if(d == nil){
48*8ccd4a63SDavid du Colombier 		werrstr("out of memory");
49*8ccd4a63SDavid du Colombier 		return nil;
50*8ccd4a63SDavid du Colombier 	}
51*8ccd4a63SDavid du Colombier 	n = dec64(d, n, t, tt - t);
52*8ccd4a63SDavid du Colombier 	if(n < 0){
53*8ccd4a63SDavid du Colombier 		free(d);
54*8ccd4a63SDavid du Colombier 		werrstr("incorrect .pem file format: bad base64 encoded data");
55*8ccd4a63SDavid du Colombier 		return nil;
56*8ccd4a63SDavid du Colombier 	}
57*8ccd4a63SDavid du Colombier 	*len = n;
58*8ccd4a63SDavid du Colombier 	return d;
59*8ccd4a63SDavid du Colombier }
60