28 #if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C)
36 #if defined(POLARSSL_MEMORY_C)
39 #define polarssl_malloc malloc
40 #define polarssl_free free
45 #if defined(POLARSSL_PEM_PARSE_C)
46 void pem_init( pem_context *ctx )
48 memset( ctx, 0,
sizeof( pem_context ) );
51 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
52 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
56 static int pem_get_iv(
const unsigned char *s,
unsigned char *iv,
size_t iv_len )
60 memset( iv, 0, iv_len );
62 for( i = 0; i < iv_len * 2; i++, s++ )
64 if( *s >=
'0' && *s <=
'9' ) j = *s -
'0';
else
65 if( *s >=
'A' && *s <=
'F' ) j = *s -
'7';
else
66 if( *s >=
'a' && *s <=
'f' ) j = *s -
'W';
else
69 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
71 iv[i >> 1] = (
unsigned char)( iv[i >> 1] | k );
77 static void pem_pbkdf1(
unsigned char *key,
size_t keylen,
79 const unsigned char *pwd,
size_t pwdlen )
82 unsigned char md5sum[16];
95 memcpy( key, md5sum, keylen );
97 memset( &md5_ctx, 0,
sizeof( md5_ctx ) );
98 memset( md5sum, 0, 16 );
102 memcpy( key, md5sum, 16 );
115 use_len = keylen - 16;
117 memcpy( key + 16, md5sum, use_len );
119 memset( &md5_ctx, 0,
sizeof( md5_ctx ) );
120 memset( md5sum, 0, 16 );
123 #if defined(POLARSSL_DES_C)
127 static void pem_des_decrypt(
unsigned char des_iv[8],
128 unsigned char *buf,
size_t buflen,
129 const unsigned char *pwd,
size_t pwdlen )
132 unsigned char des_key[8];
134 pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen );
140 memset( &des_ctx, 0,
sizeof( des_ctx ) );
141 memset( des_key, 0, 8 );
147 static void pem_des3_decrypt(
unsigned char des3_iv[8],
148 unsigned char *buf,
size_t buflen,
149 const unsigned char *pwd,
size_t pwdlen )
152 unsigned char des3_key[24];
154 pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen );
160 memset( &des3_ctx, 0,
sizeof( des3_ctx ) );
161 memset( des3_key, 0, 24 );
165 #if defined(POLARSSL_AES_C)
169 static void pem_aes_decrypt(
unsigned char aes_iv[16],
unsigned int keylen,
170 unsigned char *buf,
size_t buflen,
171 const unsigned char *pwd,
size_t pwdlen )
174 unsigned char aes_key[32];
176 pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen );
182 memset( &aes_ctx, 0,
sizeof( aes_ctx ) );
183 memset( aes_key, 0, keylen );
190 int pem_read_buffer( pem_context *ctx,
const char *header,
const char *footer,
191 const unsigned char *data,
const unsigned char *pwd,
192 size_t pwdlen,
size_t *use_len )
197 const unsigned char *s1, *s2, *end;
198 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
199 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
200 unsigned char pem_iv[16];
211 s1 = (
unsigned char *) strstr( (
const char *) data, header );
216 s2 = (
unsigned char *) strstr( (
const char *) data, footer );
218 if( s2 == NULL || s2 <= s1 )
221 s1 += strlen( header );
222 if( *s1 ==
'\r' ) s1++;
223 if( *s1 ==
'\n' ) s1++;
227 end += strlen( footer );
228 if( *end ==
'\r' ) end++;
229 if( *end ==
'\n' ) end++;
230 *use_len = end - data;
234 if( memcmp( s1,
"Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
236 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
237 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
241 if( *s1 ==
'\r' ) s1++;
242 if( *s1 ==
'\n' ) s1++;
246 #if defined(POLARSSL_DES_C)
247 if( memcmp( s1,
"DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
252 if( pem_get_iv( s1, pem_iv, 8 ) != 0 )
257 else if( memcmp( s1,
"DEK-Info: DES-CBC,", 18 ) == 0 )
262 if( pem_get_iv( s1, pem_iv, 8) != 0 )
269 #if defined(POLARSSL_AES_C)
270 if( memcmp( s1,
"DEK-Info: AES-", 14 ) == 0 )
272 if( memcmp( s1,
"DEK-Info: AES-128-CBC,", 22 ) == 0 )
274 else if( memcmp( s1,
"DEK-Info: AES-192-CBC,", 22 ) == 0 )
276 else if( memcmp( s1,
"DEK-Info: AES-256-CBC,", 22 ) == 0 )
282 if( pem_get_iv( s1, pem_iv, 16 ) != 0 )
292 if( *s1 ==
'\r' ) s1++;
293 if( *s1 ==
'\n' ) s1++;
318 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
319 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
326 #if defined(POLARSSL_DES_C)
328 pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
330 pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
333 #if defined(POLARSSL_AES_C)
335 pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
337 pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
339 pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
348 if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
366 void pem_free( pem_context *ctx )
374 memset( ctx, 0,
sizeof( pem_context ) );
378 #if defined(POLARSSL_PEM_WRITE_C)
379 int pem_write_buffer(
const char *header,
const char *footer,
380 const unsigned char *der_data,
size_t der_len,
381 unsigned char *buf,
size_t buf_len,
size_t *olen )
384 unsigned char *encode_buf, *c, *p = buf;
385 size_t len = 0, use_len = 0;
386 size_t add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
389 if( use_len + add_len > buf_len )
391 *olen = use_len + add_len;
405 memcpy( p, header, strlen( header ) );
406 p += strlen( header );
411 len = ( use_len > 64 ) ? 64 : use_len;
419 memcpy( p, footer, strlen( footer ) );
420 p += strlen( footer );
int base64_decode(unsigned char *dst, size_t *dlen, const unsigned char *src, size_t slen)
Decode a base64-formatted buffer.
#define POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
void *(* polarssl_malloc)(size_t len)
#define POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG
Unsupported key encryption algorithm.
#define POLARSSL_ERR_PEM_MALLOC_FAILED
Failed to allocate memory.
Configuration options (set of defines)
int aes_setkey_dec(aes_context *ctx, const unsigned char *key, unsigned int keysize)
AES key schedule (decryption)
void md5_finish(md5_context *ctx, unsigned char output[16])
MD5 final digest.
int des3_set3key_dec(des3_context *ctx, const unsigned char key[DES_KEY_SIZE *3])
Triple-DES key schedule (168-bit, decryption)
#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED
Private key password can't be empty.
Privacy Enhanced Mail (PEM) decoding.
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL
Output buffer too small.
Triple-DES context structure.
int aes_crypt_cbc(aes_context *ctx, int mode, size_t length, unsigned char iv[16], const unsigned char *input, unsigned char *output)
AES-CBC buffer encryption/decryption Length should be a multiple of the block size (16 bytes) ...
void(* polarssl_free)(void *ptr)
#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH
Given private key password does not allow for correct decryption.
void md5_starts(md5_context *ctx)
MD5 context setup.
#define POLARSSL_ERR_PEM_INVALID_ENC_IV
RSA IV is not in hex-format.
#define POLARSSL_ERR_PEM_INVALID_DATA
PEM string is not as expected.
int des_crypt_cbc(des_context *ctx, int mode, size_t length, unsigned char iv[8], const unsigned char *input, unsigned char *output)
DES-CBC buffer encryption/decryption.
RFC 1521 base64 encoding/decoding.
int des_setkey_dec(des_context *ctx, const unsigned char key[DES_KEY_SIZE])
DES key schedule (56-bit, decryption)
void md5_update(md5_context *ctx, const unsigned char *input, size_t ilen)
MD5 process buffer.
#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT
No PEM header or footer found.
MD5 message digest algorithm (hash function)
#define POLARSSL_ERR_PEM_BAD_INPUT_DATA
Bad input parameters to function.
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER
Invalid character in input.
int base64_encode(unsigned char *dst, size_t *dlen, const unsigned char *src, size_t slen)
Encode a buffer into base64 format.
int des3_crypt_cbc(des3_context *ctx, int mode, size_t length, unsigned char iv[8], const unsigned char *input, unsigned char *output)
3DES-CBC buffer encryption/decryption