00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "polarssl/config.h"
00027
00028 #if defined(POLARSSL_PEM_PARSE_C) || defined(POLARSSL_PEM_WRITE_C)
00029 #include "polarssl/pem.h"
00030 #include "polarssl/base64.h"
00031 #include "polarssl/des.h"
00032 #include "polarssl/aes.h"
00033 #include "polarssl/md5.h"
00034 #include "polarssl/cipher.h"
00035
00036 #if defined(POLARSSL_MEMORY_C)
00037 #include "polarssl/memory.h"
00038 #else
00039 #define polarssl_malloc malloc
00040 #define polarssl_free free
00041 #endif
00042
00043 #include <stdlib.h>
00044
00045 #if defined(POLARSSL_PEM_PARSE_C)
00046 void pem_init( pem_context *ctx )
00047 {
00048 memset( ctx, 0, sizeof( pem_context ) );
00049 }
00050
00051 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
00052 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
00053
00054
00055
00056 static int pem_get_iv( const unsigned char *s, unsigned char *iv, size_t iv_len )
00057 {
00058 size_t i, j, k;
00059
00060 memset( iv, 0, iv_len );
00061
00062 for( i = 0; i < iv_len * 2; i++, s++ )
00063 {
00064 if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
00065 if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
00066 if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
00067 return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
00068
00069 k = ( ( i & 1 ) != 0 ) ? j : j << 4;
00070
00071 iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
00072 }
00073
00074 return( 0 );
00075 }
00076
00077 static void pem_pbkdf1( unsigned char *key, size_t keylen,
00078 unsigned char *iv,
00079 const unsigned char *pwd, size_t pwdlen )
00080 {
00081 md5_context md5_ctx;
00082 unsigned char md5sum[16];
00083 size_t use_len;
00084
00085
00086
00087
00088 md5_starts( &md5_ctx );
00089 md5_update( &md5_ctx, pwd, pwdlen );
00090 md5_update( &md5_ctx, iv, 8 );
00091 md5_finish( &md5_ctx, md5sum );
00092
00093 if( keylen <= 16 )
00094 {
00095 memcpy( key, md5sum, keylen );
00096
00097 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
00098 memset( md5sum, 0, 16 );
00099 return;
00100 }
00101
00102 memcpy( key, md5sum, 16 );
00103
00104
00105
00106
00107 md5_starts( &md5_ctx );
00108 md5_update( &md5_ctx, md5sum, 16 );
00109 md5_update( &md5_ctx, pwd, pwdlen );
00110 md5_update( &md5_ctx, iv, 8 );
00111 md5_finish( &md5_ctx, md5sum );
00112
00113 use_len = 16;
00114 if( keylen < 32 )
00115 use_len = keylen - 16;
00116
00117 memcpy( key + 16, md5sum, use_len );
00118
00119 memset( &md5_ctx, 0, sizeof( md5_ctx ) );
00120 memset( md5sum, 0, 16 );
00121 }
00122
00123 #if defined(POLARSSL_DES_C)
00124
00125
00126
00127 static void pem_des_decrypt( unsigned char des_iv[8],
00128 unsigned char *buf, size_t buflen,
00129 const unsigned char *pwd, size_t pwdlen )
00130 {
00131 des_context des_ctx;
00132 unsigned char des_key[8];
00133
00134 pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen );
00135
00136 des_setkey_dec( &des_ctx, des_key );
00137 des_crypt_cbc( &des_ctx, DES_DECRYPT, buflen,
00138 des_iv, buf, buf );
00139
00140 memset( &des_ctx, 0, sizeof( des_ctx ) );
00141 memset( des_key, 0, 8 );
00142 }
00143
00144
00145
00146
00147 static void pem_des3_decrypt( unsigned char des3_iv[8],
00148 unsigned char *buf, size_t buflen,
00149 const unsigned char *pwd, size_t pwdlen )
00150 {
00151 des3_context des3_ctx;
00152 unsigned char des3_key[24];
00153
00154 pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen );
00155
00156 des3_set3key_dec( &des3_ctx, des3_key );
00157 des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
00158 des3_iv, buf, buf );
00159
00160 memset( &des3_ctx, 0, sizeof( des3_ctx ) );
00161 memset( des3_key, 0, 24 );
00162 }
00163 #endif
00164
00165 #if defined(POLARSSL_AES_C)
00166
00167
00168
00169 static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen,
00170 unsigned char *buf, size_t buflen,
00171 const unsigned char *pwd, size_t pwdlen )
00172 {
00173 aes_context aes_ctx;
00174 unsigned char aes_key[32];
00175
00176 pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen );
00177
00178 aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 );
00179 aes_crypt_cbc( &aes_ctx, AES_DECRYPT, buflen,
00180 aes_iv, buf, buf );
00181
00182 memset( &aes_ctx, 0, sizeof( aes_ctx ) );
00183 memset( aes_key, 0, keylen );
00184 }
00185 #endif
00186
00187 #endif
00188
00189
00190 int pem_read_buffer( pem_context *ctx, const char *header, const char *footer,
00191 const unsigned char *data, const unsigned char *pwd,
00192 size_t pwdlen, size_t *use_len )
00193 {
00194 int ret, enc;
00195 size_t len;
00196 unsigned char *buf;
00197 const unsigned char *s1, *s2, *end;
00198 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
00199 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
00200 unsigned char pem_iv[16];
00201 cipher_type_t enc_alg = POLARSSL_CIPHER_NONE;
00202 #else
00203 ((void) pwd);
00204 ((void) pwdlen);
00205 #endif
00206
00207
00208 if( ctx == NULL )
00209 return( POLARSSL_ERR_PEM_BAD_INPUT_DATA );
00210
00211 s1 = (unsigned char *) strstr( (const char *) data, header );
00212
00213 if( s1 == NULL )
00214 return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
00215
00216 s2 = (unsigned char *) strstr( (const char *) data, footer );
00217
00218 if( s2 == NULL || s2 <= s1 )
00219 return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
00220
00221 s1 += strlen( header );
00222 if( *s1 == '\r' ) s1++;
00223 if( *s1 == '\n' ) s1++;
00224 else return( POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT );
00225
00226 end = s2;
00227 end += strlen( footer );
00228 if( *end == '\r' ) end++;
00229 if( *end == '\n' ) end++;
00230 *use_len = end - data;
00231
00232 enc = 0;
00233
00234 if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
00235 {
00236 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
00237 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
00238 enc++;
00239
00240 s1 += 22;
00241 if( *s1 == '\r' ) s1++;
00242 if( *s1 == '\n' ) s1++;
00243 else return( POLARSSL_ERR_PEM_INVALID_DATA );
00244
00245
00246 #if defined(POLARSSL_DES_C)
00247 if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 )
00248 {
00249 enc_alg = POLARSSL_CIPHER_DES_EDE3_CBC;
00250
00251 s1 += 23;
00252 if( pem_get_iv( s1, pem_iv, 8 ) != 0 )
00253 return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
00254
00255 s1 += 16;
00256 }
00257 else if( memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 )
00258 {
00259 enc_alg = POLARSSL_CIPHER_DES_CBC;
00260
00261 s1 += 18;
00262 if( pem_get_iv( s1, pem_iv, 8) != 0 )
00263 return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
00264
00265 s1 += 16;
00266 }
00267 #endif
00268
00269 #if defined(POLARSSL_AES_C)
00270 if( memcmp( s1, "DEK-Info: AES-", 14 ) == 0 )
00271 {
00272 if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 )
00273 enc_alg = POLARSSL_CIPHER_AES_128_CBC;
00274 else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 )
00275 enc_alg = POLARSSL_CIPHER_AES_192_CBC;
00276 else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 )
00277 enc_alg = POLARSSL_CIPHER_AES_256_CBC;
00278 else
00279 return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG );
00280
00281 s1 += 22;
00282 if( pem_get_iv( s1, pem_iv, 16 ) != 0 )
00283 return( POLARSSL_ERR_PEM_INVALID_ENC_IV );
00284
00285 s1 += 32;
00286 }
00287 #endif
00288
00289 if( enc_alg == POLARSSL_CIPHER_NONE )
00290 return( POLARSSL_ERR_PEM_UNKNOWN_ENC_ALG );
00291
00292 if( *s1 == '\r' ) s1++;
00293 if( *s1 == '\n' ) s1++;
00294 else return( POLARSSL_ERR_PEM_INVALID_DATA );
00295 #else
00296 return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
00297 #endif
00298
00299 }
00300
00301 len = 0;
00302 ret = base64_decode( NULL, &len, s1, s2 - s1 );
00303
00304 if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER )
00305 return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
00306
00307 if( ( buf = (unsigned char *) polarssl_malloc( len ) ) == NULL )
00308 return( POLARSSL_ERR_PEM_MALLOC_FAILED );
00309
00310 if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
00311 {
00312 polarssl_free( buf );
00313 return( POLARSSL_ERR_PEM_INVALID_DATA + ret );
00314 }
00315
00316 if( enc != 0 )
00317 {
00318 #if defined(POLARSSL_MD5_C) && defined(POLARSSL_CIPHER_MODE_CBC) && \
00319 ( defined(POLARSSL_DES_C) || defined(POLARSSL_AES_C) )
00320 if( pwd == NULL )
00321 {
00322 polarssl_free( buf );
00323 return( POLARSSL_ERR_PEM_PASSWORD_REQUIRED );
00324 }
00325
00326 #if defined(POLARSSL_DES_C)
00327 if( enc_alg == POLARSSL_CIPHER_DES_EDE3_CBC )
00328 pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen );
00329 else if( enc_alg == POLARSSL_CIPHER_DES_CBC )
00330 pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen );
00331 #endif
00332
00333 #if defined(POLARSSL_AES_C)
00334 if( enc_alg == POLARSSL_CIPHER_AES_128_CBC )
00335 pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen );
00336 else if( enc_alg == POLARSSL_CIPHER_AES_192_CBC )
00337 pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen );
00338 else if( enc_alg == POLARSSL_CIPHER_AES_256_CBC )
00339 pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen );
00340 #endif
00341
00342
00343
00344
00345
00346
00347
00348 if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 )
00349 {
00350 polarssl_free( buf );
00351 return( POLARSSL_ERR_PEM_PASSWORD_MISMATCH );
00352 }
00353 #else
00354 polarssl_free( buf );
00355 return( POLARSSL_ERR_PEM_FEATURE_UNAVAILABLE );
00356 #endif
00357
00358 }
00359
00360 ctx->buf = buf;
00361 ctx->buflen = len;
00362
00363 return( 0 );
00364 }
00365
00366 void pem_free( pem_context *ctx )
00367 {
00368 if( ctx->buf )
00369 polarssl_free( ctx->buf );
00370
00371 if( ctx->info )
00372 polarssl_free( ctx->info );
00373
00374 memset( ctx, 0, sizeof( pem_context ) );
00375 }
00376 #endif
00377
00378 #if defined(POLARSSL_PEM_WRITE_C)
00379 int pem_write_buffer( const char *header, const char *footer,
00380 const unsigned char *der_data, size_t der_len,
00381 unsigned char *buf, size_t buf_len, size_t *olen )
00382 {
00383 int ret;
00384 unsigned char *encode_buf, *c, *p = buf;
00385 size_t len = 0, use_len = 0;
00386 size_t add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1;
00387
00388 base64_encode( NULL, &use_len, der_data, der_len );
00389 if( use_len + add_len > buf_len )
00390 {
00391 *olen = use_len + add_len;
00392 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
00393 }
00394
00395 if( ( encode_buf = polarssl_malloc( use_len ) ) == NULL )
00396 return( POLARSSL_ERR_PEM_MALLOC_FAILED );
00397
00398 if( ( ret = base64_encode( encode_buf, &use_len, der_data,
00399 der_len ) ) != 0 )
00400 {
00401 polarssl_free( encode_buf );
00402 return( ret );
00403 }
00404
00405 memcpy( p, header, strlen( header ) );
00406 p += strlen( header );
00407 c = encode_buf;
00408
00409 while( use_len )
00410 {
00411 len = ( use_len > 64 ) ? 64 : use_len;
00412 memcpy( p, c, len );
00413 use_len -= len;
00414 p += len;
00415 c += len;
00416 *p++ = '\n';
00417 }
00418
00419 memcpy( p, footer, strlen( footer ) );
00420 p += strlen( footer );
00421
00422 *p++ = '\0';
00423 *olen = p - buf;
00424
00425 polarssl_free( encode_buf );
00426 return( 0 );
00427 }
00428 #endif
00429 #endif