summaryrefslogtreecommitdiff
path: root/common/base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/base64.c')
-rw-r--r--common/base64.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/common/base64.c b/common/base64.c
index 7e66933..3f51c8d 100644
--- a/common/base64.c
+++ b/common/base64.c
@@ -190,3 +190,65 @@ p11_b64_pton (const char *src,
return (tarindex);
}
+
+int
+p11_b64_ntop (const unsigned char *src,
+ size_t srclength,
+ char *target,
+ size_t targsize,
+ int breakl)
+{
+ size_t len = 0;
+ unsigned char input[3];
+ unsigned char output[4];
+ size_t i;
+
+ while (srclength > 0) {
+ if (2 < srclength) {
+ input[0] = *src++;
+ input[1] = *src++;
+ input[2] = *src++;
+ srclength -= 3;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = input[2] & 0x3f;
+
+ } else if (0 != srclength) {
+ /* Get what's left. */
+ input[0] = input[1] = input[2] = '\0';
+ for (i = 0; i < srclength; i++)
+ input[i] = *src++;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ if (srclength == 1)
+ output[2] = 255;
+ else
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = 255;
+
+ srclength = 0;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (breakl && len % (breakl + 1) == 0) {
+ assert (len + 1 < targsize);
+ target[len++] = '\n';
+ }
+
+ assert(output[i] == 255 || output[i] < 64);
+ assert (len + 1 < targsize);
+
+ if (output[i] == 255)
+ target[len++] = Pad64;
+ else
+ target[len++] = Base64[output[i]];
+ }
+ }
+
+ assert (len < targsize);
+ target[len] = '\0'; /* Returned value doesn't count \0. */
+ return len;
+}