@@ -1238,6 +1238,8 @@ static const char *mag_deleg_ccache_unique(cmd_parms *parms, void *mconfig,
12381238
12391239#endif
12401240
1241+ #define SESS_KEYS_TOT_LEN 32
1242+
12411243static const char * mag_sess_key (cmd_parms * parms , void * mconfig , const char * w )
12421244{
12431245 struct mag_config * cfg = (struct mag_config * )mconfig ;
@@ -1247,25 +1249,82 @@ static const char *mag_sess_key(cmd_parms *parms, void *mconfig, const char *w)
12471249 const char * k ;
12481250 int l ;
12491251
1250- if (strncmp (w , "key:" , 4 ) != 0 ) {
1251- ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1252- "Invalid key format, expected prefix 'key:'" );
1253- return NULL ;
1254- }
1255- k = w + 4 ;
1252+ if (strncmp (w , "key:" , 4 ) == 0 ) {
1253+ k = w + 4 ;
1254+
1255+ l = apr_base64_decode_len (k );
1256+ val = apr_palloc (parms -> temp_pool , l );
1257+
1258+ keys .length = (int )apr_base64_decode_binary (val , k );
1259+ keys .value = (unsigned char * )val ;
12561260
1257- l = apr_base64_decode_len (k );
1258- val = apr_palloc (parms -> temp_pool , l );
1261+ if (keys .length != SESS_KEYS_TOT_LEN ) {
1262+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1263+ "Invalid key length, expected 32 got %d" ,
1264+ keys .length );
1265+ return NULL ;
1266+ }
1267+ } else if (strncmp (w , "file:" , 5 ) == 0 ) {
1268+ apr_status_t ret ;
1269+ apr_file_t * fd = NULL ;
1270+ apr_fileperms_t perms = APR_FPROT_UREAD | APR_FPROT_UWRITE ;
1271+
1272+ keys .length = SESS_KEYS_TOT_LEN ;
1273+ keys .value = apr_palloc (parms -> temp_pool , keys .length );
12591274
1260- keys .length = (int )apr_base64_decode_binary (val , k );
1261- keys .value = (unsigned char * )val ;
1275+ k = w + 5 ;
1276+
1277+ ret = apr_file_open (& fd , k , APR_FOPEN_READ , perms , parms -> temp_pool );
1278+ if (APR_STATUS_IS_ENOENT (ret )) {
1279+ ret = apr_file_open (& fd , k , APR_FOPEN_CREATE | APR_FOPEN_WRITE |
1280+ APR_FOPEN_EXCL , perms , parms -> temp_pool );
1281+ if (ret != APR_SUCCESS ) {
1282+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1283+ "Failed to create key file %s" , w );
1284+ return NULL ;
1285+ }
1286+ ret = apr_generate_random_bytes (keys .value , keys .length );
1287+ if (ret != OK ) {
1288+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1289+ "Failed to generate random sealing key!" );
1290+ apr_file_close (fd );
1291+ return NULL ;
1292+ } else {
1293+ apr_size_t bw ;
1294+ ret = apr_file_write_full (fd , keys .value , keys .length ,
1295+ & bw );
1296+ if ((ret != APR_SUCCESS ) || (bw != keys .length )) {
1297+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1298+ "Failed to store key in %s!" , w );
1299+ apr_file_close (fd );
1300+ return NULL ;
1301+ }
1302+ }
1303+ apr_file_close (fd );
1304+ fd = NULL ;
12621305
1263- if (keys .length != 32 ) {
1306+ ret = apr_file_open (& fd , k , APR_FOPEN_READ , perms ,
1307+ parms -> temp_pool );
1308+ }
1309+ if (ret == APR_SUCCESS ) {
1310+ apr_size_t br ;
1311+ ret = apr_file_read_full (fd , keys .value , keys .length , & br );
1312+ apr_file_close (fd );
1313+ if ((ret != APR_SUCCESS ) || (br != keys .length )) {
1314+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1315+ "Failed to read sealing key from %s!" , w );
1316+ return NULL ;
1317+ }
1318+ } else {
1319+ ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1320+ "Failed to open key file %s" , w );
1321+ return NULL ;
1322+ }
1323+ } else {
12641324 ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
1265- "Invalid key length, expected 32 got %d " , keys . length );
1325+ "Invalid key format, unexpected prefix in %s' " , w );
12661326 return NULL ;
12671327 }
1268-
12691328 rc = SEAL_KEY_CREATE (cfg -> pool , & cfg -> mag_skey , & keys );
12701329 if (rc != OK ) {
12711330 ap_log_error (APLOG_MARK , APLOG_ERR , 0 , parms -> server ,
0 commit comments