summaryrefslogtreecommitdiff
path: root/common/pem.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/pem.c')
-rw-r--r--common/pem.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/common/pem.c b/common/pem.c
index 3d3d284..b3c6acd 100644
--- a/common/pem.c
+++ b/common/pem.c
@@ -36,6 +36,7 @@
#include "compat.h"
#include "base64.h"
+#include "buffer.h"
#include "debug.h"
#include "pem.h"
@@ -119,7 +120,7 @@ pem_find_end (const char *data,
data += n_type;
/* Next comes the suffix */
- if (ARMOR_SUFF_L > n_data && strncmp ((char *)data, ARMOR_SUFF, ARMOR_SUFF_L) != 0)
+ if (ARMOR_SUFF_L > n_data || strncmp ((char *)data, ARMOR_SUFF, ARMOR_SUFF_L) != 0)
return NULL;
/* The end of the data */
@@ -239,3 +240,54 @@ p11_pem_parse (const char *data,
return nfound;
}
+
+char *
+p11_pem_write (const unsigned char *contents,
+ size_t length,
+ const char *type,
+ size_t *pem_len)
+{
+ p11_buffer buffer;
+ size_t estimate;
+ size_t prefix;
+ char *target;
+ int len;
+
+ return_val_if_fail (contents || !length, NULL);
+ return_val_if_fail (type, NULL);
+ return_val_if_fail (pem_len, NULL);
+
+ /* Estimate from base64 data. Algorithm from Glib reference */
+ estimate = length * 4 / 3 + 7;
+ estimate += estimate / 64 + 1;
+
+ if (!p11_buffer_init_null (&buffer, estimate + 128))
+ return_val_if_reached (NULL);
+
+ p11_buffer_add (&buffer, ARMOR_PREF_BEGIN, ARMOR_PREF_BEGIN_L);
+ p11_buffer_add (&buffer, type, -1);
+ p11_buffer_add (&buffer, ARMOR_SUFF, ARMOR_SUFF_L);
+
+ prefix = buffer.len;
+ target = p11_buffer_append (&buffer, estimate);
+ return_val_if_fail (target != NULL, NULL);
+
+ /*
+ * OpenSSL is absolutely certain that it wants its PEM base64
+ * lines to be 64 characters in len.
+ */
+
+ len = p11_b64_ntop (contents, length, target, estimate, 64);
+
+ assert (len > 0);
+ assert (len <= estimate);
+ buffer.len = prefix + len;
+
+ p11_buffer_add (&buffer, "\n", 1);
+ p11_buffer_add (&buffer, ARMOR_PREF_END, ARMOR_PREF_END_L);
+ p11_buffer_add (&buffer, type, -1);
+ p11_buffer_add (&buffer, ARMOR_SUFF, ARMOR_SUFF_L);
+ p11_buffer_add (&buffer, "\n", 1);
+
+ return p11_buffer_steal (&buffer, pem_len);
+}