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