1
0

pbe.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2015 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #ifdef HAVE_CONFIG_H
  39. # include <config.h>
  40. #endif
  41. #include <string.h>
  42. #include <stdio.h>
  43. #include <ldap.h>
  44. #include <nspr.h>
  45. #include <nss.h>
  46. #include <secmod.h>
  47. /*
  48. #include <secasn1.h>
  49. #include <secpkcs7.h>
  50. */
  51. #include <key.h>
  52. #include <certdb.h>
  53. #include <cert.h>
  54. #include <svrcore.h>
  55. #include <secmodt.h>
  56. #include <prtypes.h>
  57. #include <seccomon.h>
  58. #include <pk11func.h>
  59. #define NEED_TOK_PBE /* see slap.h - defines tokPBE and ptokPBE */
  60. #include "rever.h"
  61. #include <slap.h>
  62. #include "slapi-plugin.h"
  63. #include <uuid.h>
  64. #include <plbase64.h>
  65. struct pk11MechItem
  66. {
  67. CK_MECHANISM_TYPE type;
  68. const char *mechName;
  69. };
  70. static const struct pk11MechItem DESmech = { CKM_DES_CBC, "DES CBC encryption" };
  71. static const struct pk11MechItem AESmech = { CKM_AES_CBC, "AES CBC encryption" };
  72. static Slapi_Mutex *pbe_lock = NULL;
  73. struct pk11ContextStore
  74. {
  75. PK11SlotInfo *slot;
  76. const struct pk11MechItem *mech;
  77. PK11SymKey *key;
  78. SECItem *params;
  79. int length;
  80. unsigned char *crypt;
  81. char *algid_base64;
  82. };
  83. /*
  84. * der_algid converting functions:
  85. *
  86. * SECStatus ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii);
  87. * char * BTOA_ConvertItemToAscii(SECItem *binary_item);
  88. *
  89. */
  90. static int encode_path(char *inPlain, char **outCipher, char *path, int mech);
  91. static int decode_path(char *inCipher, char **outPlain, char *path, int mech, char *algid);
  92. static SVRCOREError genKey(struct pk11ContextStore **out, const char *token, char *path, int mech, PRArenaPool *arena, char *algid);
  93. static SVRCOREError cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out);
  94. static SVRCOREError decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len);
  95. static void freePBE(struct pk11ContextStore *store);
  96. void
  97. init_pbe_plugin()
  98. {
  99. if(!pbe_lock){
  100. pbe_lock = slapi_new_mutex();
  101. }
  102. }
  103. int
  104. encode(char *inPlain, char **outCipher, int mech)
  105. {
  106. return encode_path(inPlain, outCipher, NULL, mech);
  107. }
  108. static int
  109. encode_path(char *inPlain, char **outCipher, char *path, int mech)
  110. {
  111. struct pk11ContextStore *context = NULL;
  112. PRArenaPool *arena = NULL;
  113. unsigned char *cipher = NULL;
  114. char *tmp = NULL;
  115. char *base = NULL;
  116. int len = 0;
  117. int err;
  118. *outCipher = NULL;
  119. err = 1;
  120. if ( genKey(&context, tokPBE, path, mech, arena, NULL) == SVRCORE_Success ){
  121. /* Try an encryption */
  122. if ( cryptPassword(context, inPlain, &cipher) == SVRCORE_Success ){
  123. base = BTOA_DataToAscii(cipher, context->length);
  124. if ( base != NULL ){
  125. const char *scheme;
  126. if (mech == AES_MECH){
  127. scheme = AES_REVER_SCHEME_NAME;
  128. len = 3 + strlen(scheme)+ strlen(context->algid_base64) + strlen(base) + 1;
  129. if( (tmp = slapi_ch_malloc( len )) ){
  130. /*
  131. * {AES-<BASE64_ALG_ID>}<ENCODED PASSWORD>
  132. */
  133. sprintf( tmp, "%c%s-%s%c%s", PWD_HASH_PREFIX_START, scheme,
  134. context->algid_base64,PWD_HASH_PREFIX_END, base);
  135. }
  136. } else {
  137. /* Old school DES */
  138. scheme = DES_REVER_SCHEME_NAME;
  139. if((tmp = slapi_ch_malloc( 3 + strlen(scheme) + strlen(base)))){
  140. sprintf( tmp, "%c%s%c%s", PWD_HASH_PREFIX_START, scheme,
  141. PWD_HASH_PREFIX_END, base);
  142. }
  143. }
  144. if ( tmp != NULL ){
  145. *outCipher = tmp;
  146. tmp = NULL;
  147. err = 0;
  148. }
  149. PORT_Free(base);
  150. }
  151. }
  152. }
  153. freePBE(context);
  154. return(err);
  155. }
  156. int
  157. decode(char *inCipher, char **outPlain, int mech, char *algid)
  158. {
  159. return decode_path(inCipher, outPlain, NULL, mech, algid);
  160. }
  161. static int
  162. decode_path(char *inCipher, char **outPlain, char *path, int mech, char *algid)
  163. {
  164. struct pk11ContextStore *context = NULL;
  165. PRArenaPool *arena = NULL;
  166. unsigned char *base = NULL;
  167. char *plain = NULL;
  168. int err;
  169. int len = 0;
  170. *outPlain = NULL;
  171. err = 1;
  172. if ( genKey(&context, tokPBE, path, mech, arena, algid) == SVRCORE_Success ){
  173. /* it seems that there is memory leak in that function: bug 400170 */
  174. base = ATOB_AsciiToData(inCipher, (unsigned int*)&len);
  175. if ( base != NULL ){
  176. if ( decryptPassword(context, base, &plain, len) == SVRCORE_Success ){
  177. *outPlain = plain;
  178. err = 0;
  179. }
  180. }
  181. }
  182. slapi_ch_free_string(&algid);
  183. PORT_Free(base);
  184. PORT_FreeArena(arena, PR_TRUE);
  185. freePBE(context);
  186. return(err);
  187. }
  188. static void
  189. freePBE(struct pk11ContextStore *store)
  190. {
  191. if (store){
  192. if (store->slot)
  193. slapd_pk11_freeSlot(store->slot);
  194. if (store->key)
  195. slapd_pk11_freeSymKey(store->key);
  196. if (store->params)
  197. SECITEM_FreeItem(store->params, PR_TRUE);
  198. slapi_ch_free((void **)&store->crypt);
  199. slapi_ch_free_string(&store->algid_base64);
  200. slapi_ch_free((void **)&store);
  201. }
  202. }
  203. static SVRCOREError
  204. genKey(struct pk11ContextStore **out, const char *token, char *path, int mech, PRArenaPool *arena, char *alg)
  205. {
  206. SVRCOREError err = SVRCORE_Success;
  207. struct pk11ContextStore *store = NULL;
  208. SECItem *pwitem = NULL;
  209. SECItem *result = NULL;
  210. SECItem *salt = NULL;
  211. SECItem der_algid;
  212. SECAlgorithmID *algid = NULL;
  213. SECOidTag algoid;
  214. CK_MECHANISM pbeMech;
  215. CK_MECHANISM cryptoMech;
  216. SECAlgorithmID my_algid;
  217. char *configdir = NULL;
  218. char *der_ascii = NULL;
  219. char *iv = NULL;
  220. int free_it = 0;
  221. arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  222. store = (struct pk11ContextStore*)slapi_ch_calloc(1, sizeof(*store));
  223. if (store == NULL){
  224. err = SVRCORE_NoMemory_Error;
  225. goto done;
  226. }
  227. *out = store;
  228. /* Use the tokenName to find a PKCS11 slot */
  229. store->slot = slapd_pk11_findSlotByName((char *)token);
  230. if (store->slot == NULL){
  231. err = SVRCORE_NoSuchToken_Error;
  232. goto done;
  233. }
  234. /* Generate a key and parameters to do the encryption */
  235. if(mech == AES_MECH){
  236. store->mech = &AESmech;
  237. algoid = SEC_OID_AES_256_CBC;
  238. } else {
  239. store->mech = &DESmech;
  240. algoid = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
  241. }
  242. /* Generate a unique id, used as salt for the key generation */
  243. if ( path == NULL ){
  244. configdir = config_get_configdir();
  245. if ( configdir == NULL ){
  246. err = SVRCORE_System_Error;
  247. goto done;
  248. }
  249. } else {
  250. configdir = slapi_ch_strdup(path);
  251. }
  252. if ( slapi_uniqueIDGenerateFromNameString (&iv, NULL, configdir, strlen(configdir)) != UID_SUCCESS ){
  253. err = SVRCORE_System_Error;
  254. goto done;
  255. }
  256. pwitem = (SECItem *) PORT_Alloc(sizeof(SECItem));
  257. if (pwitem == NULL){
  258. err = SVRCORE_NoMemory_Error;
  259. goto done;
  260. }
  261. pwitem->type = siBuffer;
  262. pwitem->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
  263. if (pwitem->data == NULL){
  264. err = SVRCORE_NoMemory_Error;
  265. goto done;
  266. }
  267. strcpy((char*)pwitem->data, iv);
  268. pwitem->len = strlen(iv) + 1;
  269. salt = (SECItem *) PORT_Alloc(sizeof(SECItem));
  270. if (salt == NULL){
  271. err = SVRCORE_NoMemory_Error;
  272. goto done;
  273. }
  274. salt->type = siBuffer;
  275. salt->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
  276. if ( salt->data == NULL ){
  277. err = SVRCORE_NoMemory_Error;
  278. goto done;
  279. }
  280. strcpy((char*)salt->data, iv);
  281. salt->len = strlen(iv) + 1;
  282. PORT_Memset(&der_algid, 0, sizeof(der_algid));
  283. if(!alg){
  284. /*
  285. * This is DES, or we are encoding AES - the process is the same.
  286. */
  287. algid = slapd_pk11_createPBEAlgorithmID(algoid, 2, salt);
  288. free_it = 1; /* we need to free this algid */
  289. /*
  290. * The following is only need for AES - we need to store
  291. * algid for future decodings(unlike with DES). So convert
  292. * algid to its DER encoding. Then convert the DER to ascii,
  293. * and finally convert the DER ascii to base64 so we can store
  294. * it in the cipher prefix.
  295. */
  296. SEC_ASN1EncodeItem(arena, &der_algid, algid, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
  297. der_ascii = BTOA_ConvertItemToAscii(&der_algid);
  298. store->algid_base64 = PL_Base64Encode(der_ascii,strlen(der_ascii), NULL);
  299. slapi_ch_free_string(&der_ascii);
  300. } else {
  301. /*
  302. * We are decoding AES - use the supplied algid
  303. */
  304. PORT_Memset(&my_algid, 0, sizeof(my_algid));
  305. /* Decode the base64 der encoding */
  306. der_ascii = PL_Base64Decode(alg, strlen(alg), NULL);
  307. /* convert the der ascii to the SEC item */
  308. ATOB_ConvertAsciiToItem(&der_algid, der_ascii);
  309. SEC_ASN1DecodeItem(arena, &my_algid, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), &der_algid);
  310. SECITEM_FreeItem(&der_algid, PR_FALSE);
  311. algid = &my_algid;
  312. slapi_ch_free_string(&der_ascii);
  313. }
  314. slapi_lock_mutex(pbe_lock);
  315. store->key = slapd_pk11_pbeKeyGen(store->slot, algid, pwitem, 0, 0);
  316. if (store->key == 0){
  317. slapi_unlock_mutex(pbe_lock);
  318. err = SVRCORE_System_Error;
  319. goto done;
  320. }
  321. slapi_unlock_mutex(pbe_lock);
  322. if(mech == AES_MECH)
  323. {
  324. cryptoMech.mechanism = PK11_GetPBECryptoMechanism(algid, &store->params, pwitem);
  325. if (cryptoMech.mechanism == CKM_INVALID_MECHANISM) {
  326. err = SVRCORE_System_Error;
  327. goto done;
  328. }
  329. }
  330. else
  331. {
  332. /* DES */
  333. pbeMech.mechanism = slapd_pk11_algtagToMechanism(algoid);
  334. result = slapd_pk11_paramFromAlgid(algid);
  335. if(result){
  336. pbeMech.pParameter = result->data;
  337. pbeMech.ulParameterLen = result->len;
  338. }
  339. if(slapd_pk11_mapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
  340. PR_FALSE) != CKR_OK){
  341. err = SVRCORE_System_Error;
  342. goto done;
  343. }
  344. store->params = (SECItem *) PORT_Alloc(sizeof(SECItem));
  345. if (store->params == NULL){
  346. err = SVRCORE_System_Error;
  347. goto done;
  348. }
  349. store->params->type = store->mech->type;
  350. store->params->data = (unsigned char *)PORT_Alloc(cryptoMech.ulParameterLen);
  351. if (store->params->data == NULL){
  352. err = SVRCORE_System_Error;
  353. goto done;
  354. }
  355. memcpy(store->params->data, (unsigned char *)cryptoMech.pParameter, cryptoMech.ulParameterLen);
  356. store->params->len = cryptoMech.ulParameterLen;
  357. PORT_Free(cryptoMech.pParameter);
  358. }
  359. done:
  360. SECITEM_FreeItem(result, PR_TRUE);
  361. SECITEM_FreeItem(pwitem, PR_TRUE);
  362. SECITEM_FreeItem(salt, PR_TRUE);
  363. if(free_it){
  364. secoid_destroyAlgorithmID(algid, PR_TRUE);
  365. }
  366. slapi_ch_free_string(&configdir);
  367. slapi_ch_free_string(&iv);
  368. if (arena) {
  369. PORT_FreeArena(arena, PR_TRUE);
  370. }
  371. return (err);
  372. }
  373. static SVRCOREError
  374. decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len)
  375. {
  376. SVRCOREError err = SVRCORE_Success;
  377. unsigned char *plain = NULL;
  378. unsigned char *cipher_with_padding = NULL;
  379. SECStatus rv;
  380. PK11Context *ctx = NULL;
  381. int outLen = 0;
  382. int blocksize = 0;
  383. blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
  384. store->length = len;
  385. /*
  386. * store->length is the max. length of the returned clear text -
  387. * must be >= length of crypted bytes - also must be a multiple
  388. * of blocksize
  389. */
  390. if (blocksize != 0){
  391. store->length += blocksize - (store->length % blocksize);
  392. }
  393. /* plain will hold the returned clear text */
  394. plain = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
  395. store->length+1);
  396. if (!plain){
  397. err = SVRCORE_NoMemory_Error;
  398. goto done;
  399. }
  400. /*
  401. * create a buffer holding the original cipher bytes, padded with
  402. * zeros to a multiple of blocksize - do not need +1 since buffer is not
  403. * a string
  404. */
  405. cipher_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
  406. store->length);
  407. if (!cipher_with_padding){
  408. err = SVRCORE_NoMemory_Error;
  409. goto done;
  410. }
  411. memcpy(cipher_with_padding, cipher, len);
  412. ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_DECRYPT,
  413. store->key, store->params);
  414. if (!ctx) {
  415. err = SVRCORE_System_Error;
  416. goto done;
  417. }
  418. /*
  419. * Warning - there is a purify UMR in the NSS des code - you may see it when the
  420. * password is not a multiple of 8 bytes long
  421. */
  422. rv = slapd_pk11_cipherOp(ctx, plain, &outLen, store->length,
  423. cipher_with_padding, store->length);
  424. if (rv){
  425. err = SVRCORE_System_Error;
  426. }
  427. rv = slapd_pk11_finalize(ctx);
  428. /*
  429. * We must do the finalize, but we only want to set the err return
  430. * code if it is not already set
  431. */
  432. if (rv && (SVRCORE_Success == err))
  433. err = SVRCORE_System_Error;
  434. done:
  435. if (err == SVRCORE_Success){
  436. *out = (char *)plain;
  437. } else {
  438. slapi_ch_free((void **)&plain);
  439. }
  440. slapi_ch_free((void **)&cipher_with_padding);
  441. /* We should free the PK11Context... Something like : */
  442. if (ctx){
  443. slapd_pk11_destroyContext(ctx, PR_TRUE);
  444. }
  445. return err;
  446. }
  447. static SVRCOREError
  448. cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out)
  449. {
  450. SVRCOREError err = SVRCORE_Success;
  451. SECStatus rv;
  452. PK11Context *ctx = NULL;
  453. unsigned char *clear_with_padding = NULL; /* clear with padding up to blocksize */
  454. int blocksize = 0;
  455. int outLen = 0;
  456. blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
  457. store->length = strlen(clear);
  458. /*
  459. * The size of the clear text buffer passed to the encryption functions
  460. * must be a multiple of blocksize (usually 8 bytes) - we allocate a buffer
  461. * of this size, copy the clear text password into it, and pad the rest with
  462. * zeros.
  463. */
  464. if (blocksize != 0){
  465. store->length += blocksize - (store->length % blocksize);
  466. }
  467. /*
  468. * store->crypt will hold the crypted password - it must be >= clear length
  469. * store->crypt is freed in NSS; let's not use slapi_ch_calloc
  470. */
  471. store->crypt = (unsigned char *)calloc(sizeof(unsigned char),
  472. store->length+1);
  473. if (!store->crypt) {
  474. err = SVRCORE_NoMemory_Error;
  475. goto done;
  476. }
  477. /* Create a buffer big enough to hold the clear text password and padding */
  478. clear_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
  479. store->length+1);
  480. if (!clear_with_padding){
  481. err = SVRCORE_NoMemory_Error;
  482. goto done;
  483. }
  484. /*
  485. * Copy the clear text password into the buffer - the calloc insures the
  486. * remainder is zero padded .
  487. */
  488. strcpy((char *)clear_with_padding, clear);
  489. ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_ENCRYPT,
  490. store->key, store->params);
  491. if (!ctx) {
  492. err = SVRCORE_System_Error;
  493. goto done;
  494. }
  495. rv = slapd_pk11_cipherOp(ctx, store->crypt, &outLen, store->length,
  496. clear_with_padding, store->length);
  497. if (rv) {
  498. err = SVRCORE_System_Error;
  499. }
  500. rv = slapd_pk11_finalize(ctx);
  501. /*
  502. * We must do the finalize, but we only want to set the err return
  503. * code if it is not already set
  504. */
  505. if (rv && (SVRCORE_Success == err)){
  506. err = SVRCORE_System_Error;
  507. }
  508. done:
  509. if (err == SVRCORE_Success){
  510. *out = store->crypt;
  511. }
  512. slapi_ch_free((void **)&clear_with_padding);
  513. /* We should free the PK11Context... Something like : */
  514. if (ctx){
  515. slapd_pk11_destroyContext(ctx, PR_TRUE);
  516. }
  517. return err;
  518. }
  519. /*
  520. * The UUID name based generator was broken on x86 platforms. We use
  521. * this to generate the password encryption key. During migration,
  522. * we have to fix this so we can use the fixed generator. The env.
  523. * var USE_BROKEN_UUID tells the uuid generator to use the old
  524. * broken method to create the UUID. That will allow us to decrypt
  525. * the password to the correct clear text, then we can turn off
  526. * the broken method and use the fixed method to encrypt the
  527. * password.
  528. */
  529. char *
  530. migrateCredentials(char *oldpath, char *newpath, char *oldcred)
  531. {
  532. static char *useBrokenUUID = "USE_BROKEN_UUID=1";
  533. static char *disableBrokenUUID = "USE_BROKEN_UUID=0";
  534. char *plain = NULL;
  535. char *cipher = NULL;
  536. init_pbe_plugin();
  537. slapd_pk11_configurePKCS11(NULL, NULL, tokPBE, ptokPBE, NULL, NULL, NULL, NULL, 0, 0 );
  538. NSS_NoDB_Init(NULL);
  539. if (getenv("MIGRATE_BROKEN_PWD")) {
  540. putenv(useBrokenUUID);
  541. }
  542. if ( decode_path(oldcred, &plain, oldpath, DES_MECH, NULL) == 0 ){
  543. if (getenv("MIGRATE_BROKEN_PWD")) {
  544. putenv(disableBrokenUUID);
  545. }
  546. if ( encode_path(plain, &cipher, newpath, AES_MECH) != 0 ){
  547. return(NULL);
  548. } else {
  549. return(cipher);
  550. }
  551. } else {
  552. return(NULL);
  553. }
  554. }