diff options
Diffstat (limited to 'common/pem.c')
-rw-r--r-- | common/pem.c | 54 |
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); +} |