Plan 9 from Bell Labs’s /usr/web/sources/contrib/lucio/asn1/pem/b64.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
**	@(#) b64.c - ASCII-64 encoding and decoding
**	@(#) $Id: b64.c,v 1.2 2003/11/24 17:44:52 lucio Exp $
*/

/*
** ==================================================================
**
**      $Logfile:$
**      $RCSfile: b64.c,v $
**      $Revision: 1.2 $
**      $Date: 2003/11/24 17:44:52 $
**      $Author: lucio $
**
** ==================================================================
**
**      $Log: b64.c,v $
**      Revision 1.2  2003/11/24 17:44:52  lucio
**      Checkpoint after some progress
**
**      Revision 1.1.1.1  2003/11/10 10:34:31  lucio
**      ASN.1 developments.
**
** ==================================================================
*/

#include <u.h>
#include <libc.h>

#include "b64.h"

static char b64[] = {
	'A','B','C','D','E','F','G','H','I','J','K','L','M',
	'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
	'a','b','c','d','e','f','g','h','i','j','k','l','m',
	'n','o','p','q','r','s','t','u','v','w','x','y','z',
	'0','1','2','3','4','5','6','7','8','9','+','/',
};

long
eb64e (uchar *t, uchar *te, char *s) {
	uchar *pt = t;
	char *ps = s;
	int c;

	while (pt < te) {
		ps[0] = b64[(pt[0] & 0xFF) >> 2];
		c = ((pt[0] & 0x03) << 4);
		if (pt + 1 >= te) {
			ps[1] = b64[c];
			ps[2] = ps[3] = '=';
		} else {
			c |= (pt[1] & 0xFF) >> 4;
			ps[1] = b64[c];
			c = ((pt[1] & 0x0F) << 2);
			ps[2] = b64[c];
			if (pt + 2 >= te) {
				ps[2] = b64[c];
				ps[3] = '=';
			} else {
				c |= (pt[2] & 0xFF) >> 6;
				ps[2] = b64[c];
				ps[3] = b64[pt[2] & 0x3F];
			}
		}
		pt += 3;
		ps += 4;
		*ps = '\0';
	}
	return ps - s;
}

long
eb64 (char *t, char *s) {
	return eb64e ((uchar *) t, (uchar *) (t + strlen (t)), s);
}

long
eb64n (uchar *t, int n, char *s) {
	return eb64e (t, t + n, s);
}

long
feb64n (char *fmt, uchar *t, long sz, int w) {
	uchar *t0 = t, *te = t + sz;
	char *s= malloc (1 + ((w + 2) / 3) * 4);

	long c = 0L;

	while (t0 + w < te) {
		eb64e (t0, t0 += w, s);
		c += print (fmt, s);
	}
	eb64e (t0, te, s);
	c += print (fmt, s);
	free (s);
	return c;
}

static int u64[] = {
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	//   0.. 15
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,	//  16.. 31
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,	//  32.. 47
	52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, //  48.. 63
	-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, //  64.. 79
	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, //  80.. 95
	-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //  96..111
	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,	// 112..127

};

long
db64e (char *s, char *se, uchar *t) {
	char *ps = s;
	uchar *pt = t;
	int c0, c1, c2, c3;

	while (ps < se) {
		c0 = u64[ps[0]];
		c1 = u64[ps[1]];
		pt[0] = (c0 << 2) | ((c1 & 0xFF) >> 4);
		pt[1] = c1 << 4;
		if (ps[2] == '=') {
			pt++;
			break;
		}
		c2 = u64[ps[2]];
		pt[1] |= (c2 & 0xFF) >> 2;
		pt[2] = c2 << 6;
		if (ps[3] == '=') {
			break;
		}
		c3 = u64[ps[3]];
		pt[2] |= c3;
		ps += 4;
		pt += 3;
	}
	return pt - t;
}

long
db64 (char *s, uchar *t) {
	return db64e (s, s + strlen (s), t);
}

long
db64n (char *s, int n, uchar *t) {
	return db64e (s, s + n, t);
}

long
db64v (uchar *t, char *s) {
	int l = strlen (s);

	return db64e (s, s + l, t);
}

#undef	TEST
#ifdef	TEST
main (int argc, char *argv) {
	uchar t[512], *t0;
	char s[512], *s0;
	long n;

	s0 = strdup ("MIIBlTCCAScCAWUwDQYJKoZIhvcNAQECBQAwUTELMAkGA1UEBhMCVVMxIDAeBgNV");
	// s0 = strdup ("5XUXGx7qusDgHQGs7Jk9W8CW1fuSWUgN4w==");
	n = db64 (s0, t);
print ("Decoded: "); for (t0 = t; t0 < t + n; t0++) { print (" %02X", *t0 & 0xFF); } print ("\n");
	memcpy (t0, t, n);
	// print ("%s\n", t0);
	n = eb64e (t0, t0 + n, s);
print ("Encoded: "); for (s0 = s; s0 < s + n; s0++) { print (" %02X", *s0 & 0xFF); } print ("\n");
	print ("%s\n", s);
	// print ("%s\n", db64 ("DQo="));
}
#endif

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].