PageRenderTime 67ms CodeModel.GetById 36ms RepoModel.GetById 0ms app.codeStats 0ms

/mod_revocator-1.0.3/robject.cpp

#
C++ | 658 lines | 492 code | 61 blank | 105 comment | 48 complexity | 5891460b4fd96abcdadfea573a50f7ce MD5 | raw file
Possible License(s): Apache-2.0
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (c) 2006 Red Hat, Inc. All rights reserved.
  3. *
  4. * This copyrighted material is made available to anyone wishing to use,
  5. * modify, copy, or redistribute it subject to the terms and conditions of
  6. * the Apache License, 2.0.
  7. *
  8. * This program is distributed in the hope that it will be useful, but WITHOUT
  9. * ANY WARRANTY expressed or implied, including the implied warranties of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this
  11. * license is available at http://www.opensource.org/licenses. Any Red Hat
  12. * trademarks that are incorporated in the source code or documentation are
  13. * not subject to the Apache License, 2.0 and may only be used or replicated
  14. * with the express permission of Red Hat, Inc.
  15. *
  16. * Red Hat Author(s): Rob Crittenden
  17. * END COPYRIGHT BLOCK **/
  18. #include "pkcs11layer.h"
  19. #include "crlmanager.h"
  20. /*
  21. * revocator/object.cpp
  22. *
  23. * This file implements the NSSCKMDObject object for the
  24. * "builtin objects" cryptoki module.
  25. */
  26. /*
  27. * Finalize - not needed
  28. * Destroy - CKR_SESSION_READ_ONLY
  29. * IsTokenObject - CK_TRUE
  30. * GetAttributeCount
  31. * GetAttributeTypes
  32. * GetAttributeSize
  33. * GetAttribute
  34. * SetAttribute - unneeded
  35. * GetObjectSize
  36. */
  37. // default values for the first 6 fields
  38. const CK_OBJECT_CLASS RevocatorClass = CKO_NETSCAPE_CRL; // all revocator objects are CRLs
  39. const CK_BBOOL RevocatorTokenObject = PR_TRUE; // all revocator objects are token objects
  40. const CK_BBOOL RevocatorPrivate = PR_FALSE; // all revocator objects are public
  41. const char* RevocatorLabel = NULL; // no revocator objects have a label
  42. const CK_BBOOL RevocatorModifiable = PR_TRUE; // all revocator objects are modifiable
  43. const CK_BBOOL RevocatorIsKRL = PR_FALSE; // no revocator objects are KRLs
  44. const PRUint32 revocatorAttributeCount = 9;
  45. const CK_ATTRIBUTE_TYPE LastConstAttribute = CKA_NETSCAPE_KRL;
  46. typedef struct RevocatorFixedAttributes
  47. {
  48. CK_ATTRIBUTE attribute;
  49. NSSItem item;
  50. };
  51. const RevocatorFixedAttributes RevocatorAttributes [revocatorAttributeCount] =
  52. {
  53. // hardcoded to 9 attribute types :
  54. // 6 fixed-value fields
  55. {
  56. // class
  57. { CKA_CLASS, (CK_VOID_PTR) &RevocatorClass, sizeof(RevocatorClass) },
  58. { (void*) &RevocatorClass, sizeof(RevocatorClass) }
  59. },
  60. {
  61. // token
  62. { CKA_TOKEN, (CK_VOID_PTR) &RevocatorTokenObject, sizeof(RevocatorTokenObject) },
  63. { (void*) &RevocatorTokenObject, sizeof(RevocatorTokenObject) }
  64. },
  65. {
  66. // private
  67. { CKA_PRIVATE, (CK_VOID_PTR) &RevocatorPrivate, sizeof(RevocatorPrivate) },
  68. { (void*) &RevocatorPrivate, sizeof(RevocatorPrivate) }
  69. },
  70. {
  71. // label
  72. { CKA_LABEL, (CK_VOID_PTR) &RevocatorLabel, sizeof(RevocatorLabel) },
  73. { (void*) &RevocatorLabel, sizeof(RevocatorLabel) }
  74. },
  75. {
  76. // modifiable
  77. { CKA_MODIFIABLE, (CK_VOID_PTR) &RevocatorModifiable, sizeof(RevocatorModifiable) },
  78. { (void*) &RevocatorModifiable, sizeof(RevocatorModifiable) }
  79. },
  80. {
  81. // is KRL
  82. { CKA_NETSCAPE_KRL, (CK_VOID_PTR) &RevocatorIsKRL, sizeof(RevocatorIsKRL) },
  83. { (void*) &RevocatorIsKRL, sizeof(RevocatorIsKRL) }
  84. },
  85. {
  86. // DER CRL
  87. { CKA_VALUE, (CK_VOID_PTR) NULL, 0 },
  88. { (void*) NULL, 0 },
  89. },
  90. {
  91. // DER subject
  92. { CKA_SUBJECT, (CK_VOID_PTR) NULL, 0 },
  93. { (void*) NULL, 0 },
  94. },
  95. {
  96. // URL
  97. { CKA_NETSCAPE_URL, (CK_VOID_PTR) NULL, 0 },
  98. { (void*) NULL, 0 }
  99. }
  100. };
  101. extern "C" CK_RV
  102. revocator_mdObject_Destroy
  103. (
  104. NSSCKMDObject *mdObject,
  105. NSSCKFWObject *fwObject,
  106. NSSCKMDSession *mdSession,
  107. NSSCKFWSession *fwSession,
  108. NSSCKMDToken *mdToken,
  109. NSSCKFWToken *fwToken,
  110. NSSCKMDInstance *mdInstance,
  111. NSSCKFWInstance *fwInstance
  112. )
  113. {
  114. return CKR_SESSION_READ_ONLY;
  115. }
  116. extern "C" CK_BBOOL
  117. revocator_mdObject_IsTokenObject
  118. (
  119. NSSCKMDObject *mdObject,
  120. NSSCKFWObject *fwObject,
  121. NSSCKMDSession *mdSession,
  122. NSSCKFWSession *fwSession,
  123. NSSCKMDToken *mdToken,
  124. NSSCKFWToken *fwToken,
  125. NSSCKMDInstance *mdInstance,
  126. NSSCKFWInstance *fwInstance
  127. )
  128. {
  129. return RevocatorTokenObject;
  130. }
  131. extern "C" CK_ULONG
  132. revocator_mdObject_GetAttributeCount
  133. (
  134. NSSCKMDObject *mdObject,
  135. NSSCKFWObject *fwObject,
  136. NSSCKMDSession *mdSession,
  137. NSSCKFWSession *fwSession,
  138. NSSCKMDToken *mdToken,
  139. NSSCKFWToken *fwToken,
  140. NSSCKMDInstance *mdInstance,
  141. NSSCKFWInstance *fwInstance,
  142. CK_RV *pError
  143. )
  144. {
  145. return revocatorAttributeCount;
  146. }
  147. extern "C" CK_RV
  148. revocator_mdObject_GetAttributeTypes
  149. (
  150. NSSCKMDObject *mdObject,
  151. NSSCKFWObject *fwObject,
  152. NSSCKMDSession *mdSession,
  153. NSSCKFWSession *fwSession,
  154. NSSCKMDToken *mdToken,
  155. NSSCKFWToken *fwToken,
  156. NSSCKMDInstance *mdInstance,
  157. NSSCKFWInstance *fwInstance,
  158. CK_ATTRIBUTE_TYPE_PTR typeArray,
  159. CK_ULONG ulCount
  160. )
  161. {
  162. PRUint32 i;
  163. // hardcoded to 9 types
  164. if( revocatorAttributeCount < ulCount )
  165. {
  166. return CKR_BUFFER_TOO_SMALL;
  167. }
  168. else
  169. if (revocatorAttributeCount != ulCount)
  170. {
  171. return CKR_DEVICE_ERROR;
  172. }
  173. for( i = 0; i < revocatorAttributeCount; i++ )
  174. {
  175. typeArray[i] = RevocatorAttributes[i].attribute.type;
  176. }
  177. return CKR_OK;
  178. }
  179. extern "C" CK_ULONG
  180. revocator_mdObject_GetAttributeSize
  181. (
  182. NSSCKMDObject *mdObject,
  183. NSSCKFWObject *fwObject,
  184. NSSCKMDSession *mdSession,
  185. NSSCKFWSession *fwSession,
  186. NSSCKMDToken *mdToken,
  187. NSSCKFWToken *fwToken,
  188. NSSCKMDInstance *mdInstance,
  189. NSSCKFWInstance *fwInstance,
  190. CK_ATTRIBUTE_TYPE attribute,
  191. CK_RV *pError
  192. )
  193. {
  194. CK_ULONG i = 0;
  195. CK_ATTRIBUTE_TYPE attrtype = 0;
  196. do
  197. {
  198. attrtype = RevocatorAttributes[i].attribute.type;
  199. if (attrtype == attribute)
  200. {
  201. // hardcoded size for first 6 - return exact attribute size
  202. return RevocatorAttributes[i].attribute.ulValueLen;
  203. }
  204. i++;
  205. } while ( attrtype != LastConstAttribute );
  206. PRBool matchattr = PR_FALSE;
  207. do
  208. {
  209. attrtype = RevocatorAttributes[i].attribute.type;
  210. if ((attrtype = attribute))
  211. {
  212. matchattr = PR_TRUE;
  213. break;
  214. }
  215. i++;
  216. } while (i<revocatorAttributeCount);
  217. if (!matchattr)
  218. {
  219. // unknown attribute
  220. *pError = CKR_ATTRIBUTE_TYPE_INVALID;
  221. return 0;
  222. }
  223. // variable size for last 3 attributes
  224. // we need to return a size slightly larger than the real one, in case
  225. // the CRL increases in size between the time that NSS gets the attribute size
  226. // and the attribute value. Otherwise the CRL fetch will fail, and some
  227. // unauthorized users might be let through ...
  228. CRLInstance* io = (CRLInstance *)mdObject->etc;
  229. PR_ASSERT(io);
  230. if (!io)
  231. {
  232. // invalid object
  233. *pError = CKR_OBJECT_HANDLE_INVALID;
  234. return 0;
  235. }
  236. const PRInt32 fudgefactor = 0;
  237. switch (attribute)
  238. {
  239. case CKA_VALUE:
  240. {
  241. // return binary DER of the CRL. This will change,
  242. // and may even grow between this call and the GetAttribute call
  243. PRInt32 derlen = 0;
  244. io->acquire();
  245. const SECItem* dercrl = io->getDERCRL();
  246. if (dercrl)
  247. {
  248. derlen = dercrl->len;
  249. }
  250. io->release();
  251. return fudgefactor + derlen;
  252. }
  253. break;
  254. case CKA_SUBJECT:
  255. {
  256. // return binary DER subject of the CRL. This shouldn't change,
  257. // but it may if the CA modifies its configuration (very rare)
  258. // or in case of DNS attack, which should be detected way
  259. // before we got here by the signature check
  260. PRInt32 subjlen = 0;
  261. io->acquire();
  262. const SECItem* subject = io->getDERSubject();
  263. if (subject)
  264. {
  265. subjlen = subject->len;
  266. }
  267. io->release();
  268. return fudgefactor + subjlen;
  269. }
  270. break;
  271. case CKA_NETSCAPE_URL:
  272. {
  273. // return URL of the CRL. This will never change
  274. // but lock anyway ...
  275. PRInt32 urllen = 0;
  276. io->acquire();
  277. const char* url = io->getURL();
  278. if (url)
  279. {
  280. urllen = strlen(url);
  281. }
  282. io->release();
  283. return urllen;
  284. }
  285. break;
  286. default:
  287. {
  288. // we should not ever get here
  289. PR_ASSERT(0);
  290. *pError = CKR_ATTRIBUTE_TYPE_INVALID;
  291. return 0;
  292. }
  293. }
  294. }
  295. NSSItem* MakeItem(NSSArena *arena, const CK_ULONG len, const CK_VOID_PTR value)
  296. {
  297. NSSItem* item = (NSSItem*) PR_Malloc(sizeof(NSSItem));
  298. PR_ASSERT(item);
  299. if (!item)
  300. {
  301. return NULL;
  302. }
  303. item->size = len;
  304. item->data = PR_Malloc(len);
  305. PR_ASSERT(item->data);
  306. if (!item->data)
  307. {
  308. PR_Free(item);
  309. return NULL;
  310. }
  311. memcpy(item->data, value, len);
  312. return item;
  313. }
  314. CK_RV FreeItem(NSSItem* item)
  315. {
  316. PR_ASSERT(item);
  317. if (!item)
  318. {
  319. return CKR_HOST_MEMORY;
  320. }
  321. PR_ASSERT(item->size);
  322. PR_ASSERT(item->data);
  323. PR_Free(item->data);
  324. item->data = NULL;
  325. item->size = 0;
  326. PR_Free(item);
  327. return CKR_OK;
  328. }
  329. NSSCKFWItem revocator_GetAttribute(CRLInstance* io, CK_ATTRIBUTE_TYPE attribute,
  330. CK_RV* pError)
  331. {
  332. CK_ULONG i = 0;
  333. CK_ATTRIBUTE_TYPE attrtype = 0;
  334. NSSCKFWItem newitem;
  335. newitem.needsFreeing = PR_FALSE;
  336. newitem.item = (NSSItem*) NULL;
  337. do
  338. {
  339. attrtype = RevocatorAttributes[i].attribute.type;
  340. if (attrtype == attribute)
  341. {
  342. // hardcoded size for first 6 - return hardcoded attribute value
  343. newitem.item = (NSSItem*)&RevocatorAttributes[i].item;
  344. return newitem;
  345. }
  346. i++;
  347. } while ( attrtype != LastConstAttribute );
  348. PRBool matchattr = PR_FALSE;
  349. do
  350. {
  351. attrtype = RevocatorAttributes[i].attribute.type;
  352. if ((attrtype = attribute))
  353. {
  354. matchattr = PR_TRUE;
  355. break;
  356. }
  357. i++;
  358. } while (i<revocatorAttributeCount);
  359. if (!matchattr)
  360. {
  361. // unknown attribute
  362. *pError = CKR_ATTRIBUTE_TYPE_INVALID;
  363. return newitem;
  364. }
  365. switch (attribute)
  366. {
  367. case CKA_SUBJECT:
  368. case CKA_VALUE:
  369. case CKA_NETSCAPE_URL:
  370. {
  371. // return binary DER of the CRL. This will change,
  372. // and may even grow between this call and the GetAttribute call
  373. NSSItem* newnssitem = NULL;
  374. io->acquire();
  375. const SECItem* newsecitem = NULL;
  376. void* data = NULL;
  377. PRInt32 len = 0;
  378. switch (attribute)
  379. {
  380. case CKA_VALUE :
  381. newsecitem = io->getDERCRL();
  382. break;
  383. case CKA_SUBJECT :
  384. newsecitem = io->getDERSubject();
  385. break;
  386. case CKA_NETSCAPE_URL :
  387. {
  388. const char* url = io->getURL();
  389. if (url)
  390. {
  391. len = strlen(url);
  392. data = (void*) url;
  393. }
  394. break;
  395. }
  396. default:
  397. PR_ASSERT(0); // we definitely should not get here
  398. }
  399. if (newsecitem)
  400. {
  401. data = newsecitem->data;
  402. len = newsecitem->len;
  403. }
  404. newnssitem = MakeItem(NULL, len, data);
  405. if (newnssitem)
  406. {
  407. newitem.item = newnssitem;
  408. newitem.needsFreeing = PR_TRUE;
  409. }
  410. io->release();
  411. return newitem;
  412. }
  413. break;
  414. default:
  415. {
  416. // we should not ever get here
  417. PR_ASSERT(0);
  418. *pError = CKR_ATTRIBUTE_TYPE_INVALID;
  419. return newitem;
  420. }
  421. }
  422. }
  423. extern "C" NSSCKFWItem
  424. revocator_mdObject_GetAttribute
  425. (
  426. NSSCKMDObject *mdObject,
  427. NSSCKFWObject *fwObject,
  428. NSSCKMDSession *mdSession,
  429. NSSCKFWSession *fwSession,
  430. NSSCKMDToken *mdToken,
  431. NSSCKFWToken *fwToken,
  432. NSSCKMDInstance *mdInstance,
  433. NSSCKFWInstance *fwInstance,
  434. CK_ATTRIBUTE_TYPE attribute,
  435. CK_RV* pError
  436. )
  437. {
  438. NSSCKFWItem mdItem;
  439. mdItem.needsFreeing = PR_FALSE;
  440. mdItem.item = (NSSItem*) NULL;
  441. // variable size for last 3 attributes . We return an NSSItem
  442. // with the actual data size
  443. CRLInstance* io = (CRLInstance *)mdObject->etc;
  444. PR_ASSERT(io);
  445. if (!io)
  446. {
  447. // invalid object
  448. *pError = CKR_OBJECT_HANDLE_INVALID;
  449. return mdItem;
  450. }
  451. mdItem = revocator_GetAttribute(io, attribute, pError);
  452. return mdItem;
  453. }
  454. extern "C" CK_RV
  455. revocator_mdObject_FreeAttribute
  456. (
  457. NSSCKFWItem * item
  458. )
  459. {
  460. PR_ASSERT(item);
  461. PR_ASSERT(item->item);
  462. if (!item || !item->item)
  463. {
  464. return CKR_HOST_MEMORY;
  465. }
  466. CK_RV rv = FreeItem(item->item);
  467. item->item = NULL;
  468. return rv;
  469. }
  470. /*
  471. extern "C" CK_ULONG
  472. revocator_mdObject_GetObjectSize
  473. (
  474. NSSCKMDObject *mdObject,
  475. NSSCKFWObject *fwObject,
  476. NSSCKMDSession *mdSession,
  477. NSSCKFWSession *fwSession,
  478. NSSCKMDToken *mdToken,
  479. NSSCKFWToken *fwToken,
  480. NSSCKMDInstance *mdInstance,
  481. NSSCKFWInstance *fwInstance,
  482. CK_RV *pError
  483. )
  484. {
  485. // do not implement
  486. CRLInstance* io = (revocatorInternalObject *)mdObject->etc;
  487. CK_ULONG i;
  488. CK_ULONG rv = sizeof(CK_ULONG);
  489. for( i = 0; i < io->n; i++ )
  490. {
  491. rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
  492. }
  493. return rv;
  494. }
  495. */
  496. extern "C" CK_BBOOL
  497. revocator_attrmatch
  498. (
  499. CK_ATTRIBUTE_PTR a,
  500. const NSSItem* b
  501. )
  502. {
  503. PRBool prb;
  504. if( a->ulValueLen != b->size )
  505. {
  506. return CK_FALSE;
  507. }
  508. prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
  509. if( PR_TRUE == prb )
  510. {
  511. return CK_TRUE;
  512. }
  513. else
  514. {
  515. return CK_FALSE;
  516. }
  517. }
  518. extern "C" CK_BBOOL
  519. revocator_match
  520. (
  521. CK_ATTRIBUTE_PTR pTemplate,
  522. CK_ULONG ulAttributeCount,
  523. CRLInstance* o
  524. )
  525. {
  526. CK_ULONG i;
  527. for( i = 0; i < ulAttributeCount; i++ )
  528. {
  529. CK_ULONG j;
  530. for( j = 0; j < revocatorAttributeCount; j++ )
  531. {
  532. if( RevocatorAttributes[j].attribute.type == pTemplate[i].type )
  533. {
  534. CK_RV err;
  535. NSSCKFWItem attr = revocator_GetAttribute(o, pTemplate[i].type, &err);
  536. PR_ASSERT(attr.item);
  537. if (!attr.item)
  538. {
  539. continue;
  540. }
  541. if( CK_FALSE == revocator_attrmatch(&pTemplate[i], attr.item) )
  542. {
  543. return CK_FALSE;
  544. }
  545. else
  546. {
  547. break;
  548. }
  549. }
  550. }
  551. if( j == revocatorAttributeCount )
  552. {
  553. // Loop ran to the end: no matching attribute
  554. return CK_FALSE;
  555. }
  556. }
  557. // Every attribute passed
  558. return CK_TRUE;
  559. }
  560. extern "C" const NSSCKMDObject
  561. revocator_prototype_mdObject = {
  562. (void *)NULL, // etc
  563. NULL, // Finalize
  564. revocator_mdObject_Destroy,
  565. revocator_mdObject_IsTokenObject,
  566. revocator_mdObject_GetAttributeCount,
  567. revocator_mdObject_GetAttributeTypes,
  568. revocator_mdObject_GetAttributeSize,
  569. revocator_mdObject_GetAttribute,
  570. revocator_mdObject_FreeAttribute,
  571. NULL, // SetAttribute
  572. NULL, //revocator_mdObject_GetObjectSize,
  573. (void *)NULL // null terminator
  574. };
  575. NSS_IMPLEMENT NSSCKMDObject*
  576. revocator_CreateMDObject
  577. (
  578. NSSArena *arena,
  579. CRLInstance *io,
  580. CK_RV *pError
  581. )
  582. {
  583. // everything is already done for us in the constructor
  584. PR_ASSERT(io);
  585. if (io)
  586. {
  587. return io->getMdObject();
  588. }
  589. else
  590. {
  591. return NULL;
  592. }
  593. }