Source: security/identity/basic-identity-storage.js

  1. /**
  2. * Copyright (C) 2015-2016 Regents of the University of California.
  3. * @author: Jeff Thompson <jefft0@remap.ucla.edu>
  4. * From ndn-cxx security by Yingdi Yu <yingdi@cs.ucla.edu>.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. * A copy of the GNU Lesser General Public License is in the file COPYING.
  19. */
  20. /** @ignore */
  21. var Name = require('../../name.js').Name; /** @ignore */
  22. var Blob = require('../../util/blob.js').Blob; /** @ignore */
  23. var Sqlite3Promise = require('../../util/sqlite3-promise.js').Sqlite3Promise; /** @ignore */
  24. var KeyLocator = require('../../key-locator.js').KeyLocator; /** @ignore */
  25. var SecurityException = require('../security-exception.js').SecurityException; /** @ignore */
  26. var IdentityCertificate = require('../certificate/identity-certificate.js').IdentityCertificate; /** @ignore */
  27. var IdentityStorage = require('./identity-storage.js').IdentityStorage; /** @ignore */
  28. var path = require('path');
  29. /**
  30. * BasicIdentityStorage extends IdentityStorage to implement basic storage of
  31. * identity, public keys and certificates using the Node.js sqlite3 module.
  32. * Create a new BasicIdentityStorage to use the SQLite3 file in the default
  33. * location, or the optional given file.
  34. * @param {string} databaseFilePath (optional) The path of the SQLite3 file. If
  35. * omitted, use the default file (~/.ndn/ndnsec-public-info.db).
  36. * @constructor
  37. */
  38. var BasicIdentityStorage = function BasicIdentityStorage(databaseFilePath)
  39. {
  40. // Call the base constructor.
  41. IdentityStorage.call(this);
  42. databaseFilePath = databaseFilePath || path.join
  43. (BasicIdentityStorage.getUserHomePath(), ".ndn", "ndnsec-public-info.db");
  44. this.database_ = new Sqlite3Promise
  45. (databaseFilePath, BasicIdentityStorage.initializeDatabasePromise_);
  46. };
  47. BasicIdentityStorage.prototype = new IdentityStorage();
  48. BasicIdentityStorage.prototype.name = "BasicIdentityStorage";
  49. exports.BasicIdentityStorage = BasicIdentityStorage;
  50. /**
  51. * Check if the specified identity already exists.
  52. * @param {Name} identityName The identity name.
  53. * @param {boolean} useSync (optional) If true then return a rejected promise
  54. * since this only supports async code.
  55. * @returns {Promise} A promise which returns true if the identity exists.
  56. */
  57. BasicIdentityStorage.prototype.doesIdentityExistPromise = function
  58. (identityName, useSync)
  59. {
  60. if (useSync)
  61. return Promise.reject(new SecurityException(new Error
  62. ("BasicIdentityStorage.doesIdentityExistPromise is only supported for async")));
  63. return this.getPromise_
  64. ("SELECT count(*) FROM Identity WHERE identity_name=?", identityName.toUri())
  65. .then(function(row) {
  66. if (row["count(*)"] > 0)
  67. return Promise.resolve(true);
  68. else
  69. return Promise.resolve(false);
  70. });
  71. };
  72. /**
  73. * Add a new identity. Do nothing if the identity already exists.
  74. * @param {Name} identityName The identity name to be added.
  75. * @param {boolean} useSync (optional) If true then return a rejected promise
  76. * since this only supports async code.
  77. * @return {Promise} A promise which fulfills when the identity is added.
  78. */
  79. BasicIdentityStorage.prototype.addIdentityPromise = function(identityName, useSync)
  80. {
  81. if (useSync)
  82. return Promise.reject(new SecurityException(new Error
  83. ("BasicIdentityStorage.addIdentityPromise is only supported for async")));
  84. var thisStorage = this;
  85. var identityUri = identityName.toUri();
  86. return this.doesIdentityExistPromise(identityName)
  87. .then(function(exists) {
  88. if (exists)
  89. return Promise.resolve();
  90. return thisStorage.runPromise_
  91. ("INSERT INTO Identity (identity_name) VALUES(?)", identityUri);
  92. });
  93. };
  94. /**
  95. * Check if the specified key already exists.
  96. * @param {Name} keyName The name of the key.
  97. * @param {boolean} useSync (optional) If true then return a rejected promise
  98. * since this only supports async code.
  99. * @return {Promise} A promise which returns true if the key exists.
  100. */
  101. BasicIdentityStorage.prototype.doesKeyExistPromise = function(keyName, useSync)
  102. {
  103. if (useSync)
  104. return Promise.reject(new SecurityException(new Error
  105. ("BasicIdentityStorage.doesKeyExistPromise is only supported for async")));
  106. var keyId = keyName.get(-1).toEscapedString();
  107. var identityName = keyName.getPrefix(-1);
  108. return this.getPromise_
  109. ("SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?",
  110. [identityName.toUri(), keyId])
  111. .then(function(row) {
  112. if (row["count(*)"] > 0)
  113. return Promise.resolve(true);
  114. else
  115. return Promise.resolve(false);
  116. });
  117. };
  118. /**
  119. * Add a public key to the identity storage. Also call addIdentity to ensure
  120. * that the identityName for the key exists. However, if the key already
  121. * exists, do nothing.
  122. * @param {Name} keyName The name of the public key to be added.
  123. * @param {number} keyType Type of the public key to be added from KeyType, such
  124. * as KeyType.RSA..
  125. * @param {Blob} publicKeyDer A blob of the public key DER to be added.
  126. * @param {boolean} useSync (optional) If true then return a rejected promise
  127. * since this only supports async code.
  128. * @return {Promise} A promise which fulfills when complete.
  129. */
  130. BasicIdentityStorage.prototype.addKeyPromise = function
  131. (keyName, keyType, publicKeyDer, useSync)
  132. {
  133. if (useSync)
  134. return Promise.reject(new SecurityException(new Error
  135. ("BasicIdentityStorage.addKeyPromise is only supported for async")));
  136. if (keyName.size() === 0)
  137. return Promise.resolve();
  138. var thisStorage = this;
  139. return this.doesKeyExistPromise(keyName)
  140. .then(function(exists) {
  141. if (exists)
  142. return Promise.resolve();
  143. var identityName = keyName.getPrefix(-1);
  144. var identityUri = identityName.toUri();
  145. return thisStorage.addIdentityPromise(identityName)
  146. .then(function() {
  147. var keyId = keyName.get(-1).toEscapedString();
  148. var keyBuffer = publicKeyDer.buf();
  149. return thisStorage.runPromise_
  150. ("INSERT INTO Key (identity_name, key_identifier, key_type, public_key) VALUES(?,?,?,?)",
  151. [identityUri, keyId, keyType, keyBuffer]);
  152. });
  153. });
  154. };
  155. /**
  156. * Get the public key DER blob from the identity storage.
  157. * @param {Name} keyName The name of the requested public key.
  158. * @param {boolean} useSync (optional) If true then return a rejected promise
  159. * since this only supports async code.
  160. * @return {Promise} A promise which returns the DER Blob, or a promise rejected
  161. * with SecurityException if the key doesn't exist.
  162. */
  163. BasicIdentityStorage.prototype.getKeyPromise = function(keyName, useSync)
  164. {
  165. if (useSync)
  166. return Promise.reject(new SecurityException(new Error
  167. ("BasicIdentityStorage.getKeyPromise is only supported for async")));
  168. if (keyName.size() === 0)
  169. return Promise.reject(new SecurityException(new Error
  170. ("BasicIdentityStorage::getKeyPromise: Empty keyName")));
  171. var identityUri = keyName.getPrefix(-1).toUri();
  172. var keyId = keyName.get(-1).toEscapedString();
  173. return this.getPromise_
  174. ("SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?",
  175. [identityUri, keyId])
  176. .then(function(row) {
  177. if (row)
  178. return Promise.resolve(new Blob(row.public_key, false));
  179. else
  180. return Promise.reject(new SecurityException(new Error
  181. ("BasicIdentityStorage::getKeyPromise: The key does not exist")));
  182. });
  183. };
  184. /**
  185. * Check if the specified certificate already exists.
  186. * @param {Name} certificateName The name of the certificate.
  187. * @param {boolean} useSync (optional) If true then return a rejected promise
  188. * since this only supports async code.
  189. * @return {Promise} A promise which returns true if the certificate exists.
  190. */
  191. BasicIdentityStorage.prototype.doesCertificateExistPromise = function
  192. (certificateName, useSync)
  193. {
  194. if (useSync)
  195. return Promise.reject(new SecurityException(new Error
  196. ("BasicIdentityStorage.doesCertificateExistPromise is only supported for async")));
  197. return this.getPromise_
  198. ("SELECT count(*) FROM Certificate WHERE cert_name=?", certificateName.toUri())
  199. .then(function(row) {
  200. if (row["count(*)"] > 0)
  201. return Promise.resolve(true);
  202. else
  203. return Promise.resolve(false);
  204. });
  205. };
  206. /**
  207. * Add a certificate to the identity storage. Also call addKey to ensure that
  208. * the certificate key exists. If the certificate is already installed, don't
  209. * replace it.
  210. * @param {IdentityCertificate} certificate The certificate to be added. This
  211. * makes a copy of the certificate.
  212. * @param {boolean} useSync (optional) If true then return a rejected promise
  213. * since this only supports async code.
  214. * @return {Promise} A promise which fulfills when finished.
  215. */
  216. BasicIdentityStorage.prototype.addCertificatePromise = function
  217. (certificate, useSync)
  218. {
  219. if (useSync)
  220. return Promise.reject(new SecurityException(new Error
  221. ("BasicIdentityStorage.addCertificatePromise is only supported for async")));
  222. var certificateName = certificate.getName();
  223. var keyName = certificate.getPublicKeyName();
  224. var thisStorage = this;
  225. return this.addKeyPromise
  226. (keyName, certificate.getPublicKeyInfo().getKeyType(),
  227. certificate.getPublicKeyInfo().getKeyDer(), useSync)
  228. .then(function() {
  229. return thisStorage.doesCertificateExistPromise(certificateName);
  230. })
  231. .then(function(exists) {
  232. if (exists)
  233. return Promise.resolve();
  234. var keyId = keyName.get(-1).toEscapedString();
  235. var identity = keyName.getPrefix(-1);
  236. // Insert the certificate.
  237. var signature = certificate.getSignature();
  238. var signerName = KeyLocator.getFromSignature(signature).getKeyName();
  239. // Convert from milliseconds to seconds since 1/1/1970.
  240. var notBefore = Math.floor(certificate.getNotBefore() / 1000.0);
  241. var notAfter = Math.floor(certificate.getNotAfter() / 1000.0);
  242. var encodedCert = certificate.wireEncode().buf();
  243. return thisStorage.runPromise_
  244. ("INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data) " +
  245. "VALUES (?,?,?,?,?,?,?)",
  246. [certificateName.toUri(), signerName.toUri(), identity.toUri(), keyId,
  247. notBefore, notAfter, encodedCert]);
  248. });
  249. };
  250. /**
  251. * Get a certificate from the identity storage.
  252. * @param {Name} certificateName The name of the requested certificate.
  253. * @param {boolean} useSync (optional) If true then return a rejected promise
  254. * since this only supports async code.
  255. * @return {Promise} A promise which returns the requested
  256. * IdentityCertificate, or a promise rejected with SecurityException if the
  257. * certificate doesn't exist.
  258. */
  259. BasicIdentityStorage.prototype.getCertificatePromise = function
  260. (certificateName, useSync)
  261. {
  262. if (useSync)
  263. return Promise.reject(new SecurityException(new Error
  264. ("BasicIdentityStorage.getCertificatePromise is only supported for async")));
  265. return this.getPromise_
  266. ("SELECT certificate_data FROM Certificate WHERE cert_name=?",
  267. certificateName.toUri())
  268. .then(function(row) {
  269. if (row) {
  270. var certificate = new IdentityCertificate()
  271. try {
  272. certificate.wireDecode(new Blob(row.certificate_data, false))
  273. } catch (ex) {
  274. return Promise.reject(new SecurityException(new Error
  275. ("BasicIdentityStorage.getCertificatePromise: The certificate cannot be decoded")));
  276. }
  277. return Promise.resolve(certificate);
  278. }
  279. else
  280. return Promise.reject(new SecurityException(new Error
  281. ("BasicIdentityStorage.getCertificatePromise: The certificate does not exist")));
  282. });
  283. };
  284. /*****************************************
  285. * Get/Set Default *
  286. *****************************************/
  287. /**
  288. * Get the default identity.
  289. * @param {boolean} useSync (optional) If true then return a rejected promise
  290. * since this only supports async code.
  291. * @return {Promise} A promise which returns the Name of default identity, or a
  292. * promise rejected with SecurityException if the default identity is not set.
  293. */
  294. BasicIdentityStorage.prototype.getDefaultIdentityPromise = function(useSync)
  295. {
  296. if (useSync)
  297. return Promise.reject(new SecurityException(new Error
  298. ("BasicIdentityStorage.getDefaultIdentityPromise is only supported for async")));
  299. return this.getPromise_
  300. ("SELECT identity_name FROM Identity WHERE default_identity=1")
  301. .then(function(row) {
  302. if (row)
  303. return Promise.resolve(new Name(row.identity_name));
  304. else
  305. return Promise.reject(new SecurityException(new Error
  306. ("BasicIdentityStorage::getDefaultIdentityPromise: The default identity is not defined")));
  307. });
  308. };
  309. /**
  310. * Get the default key name for the specified identity.
  311. * @param {Name} identityName The identity name.
  312. * @param {boolean} useSync (optional) If true then return a rejected promise
  313. * since this only supports async code.
  314. * @return {Promise} A promise which returns the default key Name, or a promise
  315. * rejected with SecurityException if the default key name for the identity is
  316. * not set.
  317. */
  318. BasicIdentityStorage.prototype.getDefaultKeyNameForIdentityPromise = function
  319. (identityName, useSync)
  320. {
  321. if (useSync)
  322. return Promise.reject(new SecurityException(new Error
  323. ("BasicIdentityStorage.getDefaultKeyNameForIdentityPromise is only supported for async")));
  324. return this.getPromise_
  325. ("SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1",
  326. identityName.toUri())
  327. .then(function(row) {
  328. if (row)
  329. return Promise.resolve(new Name(identityName).append(row.key_identifier));
  330. else
  331. return Promise.reject(new SecurityException(new Error
  332. ("BasicIdentityStorage::getDefaultKeyNameForIdentityPromise: The default key for the identity is not defined")));
  333. });
  334. };
  335. /**
  336. * Get the default certificate name for the specified key.
  337. * @param {Name} keyName The key name.
  338. * @param {boolean} useSync (optional) If true then return a rejected promise
  339. * since this only supports async code.
  340. * @return {Promise} A promise which returns the default certificate Name, or a
  341. * promise rejected with SecurityException if the default certificate name for
  342. * the key name is not set.
  343. */
  344. BasicIdentityStorage.prototype.getDefaultCertificateNameForKeyPromise = function
  345. (keyName, useSync)
  346. {
  347. if (useSync)
  348. return Promise.reject(new SecurityException(new Error
  349. ("BasicIdentityStorage.getDefaultCertificateNameForKeyPromise is only supported for async")));
  350. var keyId = keyName.get(-1).toEscapedString();
  351. var identityName = keyName.getPrefix(-1);
  352. return this.getPromise_
  353. ("SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1",
  354. [identityName.toUri(), keyId])
  355. .then(function(row) {
  356. if (row)
  357. return Promise.resolve(new Name(row.cert_name));
  358. else
  359. return Promise.reject(new SecurityException(new Error
  360. ("BasicIdentityStorage::getDefaultCertificateNameForKeyPromise: The default certificate for the key name is not defined")));
  361. });
  362. };
  363. /**
  364. * Append all the identity names to the nameList.
  365. * @param {Array<Name>} nameList Append result names to nameList.
  366. * @param {boolean} isDefault If true, add only the default identity name. If
  367. * false, add only the non-default identity names.
  368. * @param {boolean} useSync (optional) If true then return a rejected promise
  369. * since this only supports async code.
  370. * @return {Promise} A promise which fulfills when the names are added to
  371. * nameList.
  372. */
  373. BasicIdentityStorage.prototype.getAllIdentitiesPromise = function
  374. (nameList, isDefault, useSync)
  375. {
  376. if (useSync)
  377. return Promise.reject(new SecurityException(new Error
  378. ("BasicIdentityStorage.getAllIdentitiesPromise is only supported for async")));
  379. var query;
  380. if (isDefault)
  381. query = "SELECT identity_name FROM Identity WHERE default_identity=1";
  382. else
  383. query = "SELECT identity_name FROM Identity WHERE default_identity=0";
  384. return this.eachPromise_(query, [], function(err, row) {
  385. nameList.push(new Name(row.identity_name));
  386. });
  387. };
  388. /**
  389. * Append all the key names of a particular identity to the nameList.
  390. * @param {Name} identityName The identity name to search for.
  391. * @param {Array<Name>} nameList Append result names to nameList.
  392. * @param {boolean} isDefault If true, add only the default key name. If false,
  393. * add only the non-default key names.
  394. * @param {boolean} useSync (optional) If true then return a rejected promise
  395. * since this only supports async code.
  396. * @return {Promise} A promise which fulfills when the names are added to
  397. * nameList.
  398. */
  399. BasicIdentityStorage.prototype.getAllKeyNamesOfIdentityPromise = function
  400. (identityName, nameList, isDefault, useSync)
  401. {
  402. if (useSync)
  403. return Promise.reject(new SecurityException(new Error
  404. ("BasicIdentityStorage.getAllKeyNamesOfIdentityPromise is only supported for async")));
  405. var query;
  406. if (isDefault)
  407. query = "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?";
  408. else
  409. query = "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?";
  410. return this.eachPromise_(query, identityName.toUri(), function(err, row) {
  411. nameList.push(new Name(identityName).append(row.key_identifier));
  412. });
  413. };
  414. /**
  415. * Append all the certificate names of a particular key name to the nameList.
  416. * @param {Name} keyName The key name to search for.
  417. * @param {Array<Name>} nameList Append result names to nameList.
  418. * @param {boolean} isDefault If true, add only the default certificate name.
  419. * If false, add only the non-default certificate names.
  420. * @param {boolean} useSync (optional) If true then return a rejected promise
  421. * since this only supports async code.
  422. * @return {Promise} A promise which fulfills when the names are added to
  423. * nameList.
  424. */
  425. BasicIdentityStorage.prototype.getAllCertificateNamesOfKeyPromise = function
  426. (keyName, nameList, isDefault, useSync)
  427. {
  428. if (useSync)
  429. return Promise.reject(new SecurityException(new Error
  430. ("BasicIdentityStorage.getAllCertificateNamesOfKeyPromise is only supported for async")));
  431. var query;
  432. if (isDefault)
  433. query = "SELECT cert_name FROM Certificate" +
  434. " WHERE default_cert=1 and identity_name=? and key_identifier=?";
  435. else
  436. query = "SELECT cert_name FROM Certificate" +
  437. " WHERE default_cert=0 and identity_name=? and key_identifier=?";
  438. return this.eachPromise_
  439. (query, [keyName.getPrefix(-1).toUri(), keyName.get(-1).toEscapedString()],
  440. function(err, row) {
  441. nameList.push(new Name(row.cert_name));
  442. });
  443. };
  444. /**
  445. * Set the default identity. If the identityName does not exist, then clear the
  446. * default identity so that getDefaultIdentity() throws an exception.
  447. * @param {Name} identityName The default identity name.
  448. * @param {boolean} useSync (optional) If true then return a rejected promise
  449. * since this only supports async code.
  450. * @return {Promise} A promise which fulfills when the default identity is set.
  451. */
  452. BasicIdentityStorage.prototype.setDefaultIdentityPromise = function
  453. (identityName, useSync)
  454. {
  455. if (useSync)
  456. return Promise.reject(new SecurityException(new Error
  457. ("BasicIdentityStorage.setDefaultIdentityPromise is only supported for async")));
  458. var thisStorage = this;
  459. // Reset the previous default identity.
  460. return this.runPromise_
  461. ("UPDATE Identity SET default_identity=0 WHERE default_identity=1")
  462. .then(function() {
  463. // Set the current default identity.
  464. return thisStorage.runPromise_
  465. ("UPDATE Identity SET default_identity=1 WHERE identity_name=?",
  466. identityName.toUri());
  467. });
  468. };
  469. /**
  470. * Set a key as the default key of an identity. The identity name is inferred
  471. * from keyName.
  472. * @param {Name} keyName The name of the key.
  473. * @param {Name} identityNameCheck (optional) The identity name to check that the
  474. * keyName contains the same identity name. If an empty name, it is ignored.
  475. * @param {boolean} useSync (optional) If true then return a rejected promise
  476. * since this only supports async code.
  477. * @return {Promise} A promise which fulfills when the default key name is set.
  478. */
  479. BasicIdentityStorage.prototype.setDefaultKeyNameForIdentityPromise = function
  480. (keyName, identityNameCheck, useSync)
  481. {
  482. useSync = (typeof identityNameCheck === "boolean") ? identityNameCheck : useSync;
  483. identityNameCheck = (identityNameCheck instanceof Name) ? identityNameCheck : null;
  484. if (useSync)
  485. return Promise.reject(new SecurityException(new Error
  486. ("BasicIdentityStorage.setDefaultKeyNameForIdentityPromise is only supported for async")));
  487. var keyId = keyName.get(-1).toEscapedString();
  488. var identityName = keyName.getPrefix(-1);
  489. if (identityNameCheck != null && identityNameCheck.size() != 0 &&
  490. !identityNameCheck.equals(identityName))
  491. return Promise.reject(new SecurityException(new Error
  492. ("Specified identity name does not match the key name")));
  493. var thisStorage = this;
  494. // Reset the previous default key.
  495. var identityUri = identityName.toUri();
  496. return this.runPromise_
  497. ("UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?",
  498. identityUri)
  499. .then(function() {
  500. // Set the current default key.
  501. return thisStorage.runPromise_
  502. ("UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?",
  503. [identityUri, keyId]);
  504. });
  505. };
  506. /**
  507. * Set the default key name for the specified identity.
  508. * @param {Name} keyName The key name.
  509. * @param {Name} certificateName The certificate name.
  510. * @param {boolean} useSync (optional) If true then return a rejected promise
  511. * since this only supports async code.
  512. * @return {Promise} A promise which fulfills when the default certificate name
  513. * is set.
  514. */
  515. BasicIdentityStorage.prototype.setDefaultCertificateNameForKeyPromise = function
  516. (keyName, certificateName, useSync)
  517. {
  518. if (useSync)
  519. return Promise.reject(new SecurityException(new Error
  520. ("BasicIdentityStorage.setDefaultCertificateNameForKeyPromise is only supported for async")));
  521. var keyId = keyName.get(-1).toEscapedString();
  522. var identityName = keyName.getPrefix(-1);
  523. var thisStorage = this;
  524. // Reset the previous default certificate.
  525. var identityUri = identityName.toUri();
  526. return this.runPromise_
  527. ("UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?",
  528. [identityUri, keyId])
  529. .then(function() {
  530. // Set the current default certificate.
  531. return thisStorage.runPromise_
  532. ("UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?",
  533. [identityUri, keyId, certificateName.toUri()]);
  534. });
  535. };
  536. /*****************************************
  537. * Delete Methods *
  538. *****************************************/
  539. /**
  540. * Delete a certificate.
  541. * @param {Name} certificateName The certificate name.
  542. * @param {boolean} useSync (optional) If true then return a rejected promise
  543. * since this only supports async code.
  544. * @return {Promise} A promise which fulfills when the certificate info is
  545. * deleted.
  546. */
  547. BasicIdentityStorage.prototype.deleteCertificateInfoPromise = function
  548. (certificateName, useSync)
  549. {
  550. if (useSync)
  551. return Promise.reject(new SecurityException(new Error
  552. ("BasicIdentityStorage.deleteCertificateInfoPromise is only supported for async")));
  553. if (certificateName.size() === 0)
  554. return
  555. return this.runPromise_
  556. ("DELETE FROM Certificate WHERE cert_name=?", certificateName.toUri());
  557. };
  558. /**
  559. * Delete a public key and related certificates.
  560. * @param {Name} keyName The key name.
  561. * @param {boolean} useSync (optional) If true then return a rejected promise
  562. * since this only supports async code.
  563. * @return {Promise} A promise which fulfills when the public key info is
  564. * deleted.
  565. */
  566. BasicIdentityStorage.prototype.deletePublicKeyInfoPromise = function(keyName, useSync)
  567. {
  568. if (useSync)
  569. return Promise.reject(new SecurityException(new Error
  570. ("BasicIdentityStorage.deletePublicKeyInfoPromise is only supported for async")));
  571. if (keyName.size() === 0)
  572. return Promise.resolve();
  573. var thisStorage = this;
  574. var keyId = keyName.get(-1).toEscapedString();
  575. var identityName = keyName.getPrefix(-1);
  576. return this.runPromise_
  577. ("DELETE FROM Certificate WHERE identity_name=? AND key_identifier=?",
  578. [identityName.toUri(), keyId])
  579. .then(function() {
  580. return thisStorage.runPromise_
  581. ("DELETE FROM Key WHERE identity_name=? and key_identifier=?",
  582. [identityName.toUri(), keyId]);
  583. });
  584. };
  585. /**
  586. * Delete an identity and related public keys and certificates.
  587. * @param {Name} identityName The identity name.
  588. * @param {boolean} useSync (optional) If true then return a rejected promise
  589. * since this only supports async code.
  590. * @return {Promise} A promise which fulfills when the identity info is deleted.
  591. */
  592. BasicIdentityStorage.prototype.deleteIdentityInfoPromise = function
  593. (identityName, useSync)
  594. {
  595. if (useSync)
  596. return Promise.reject(new SecurityException(new Error
  597. ("BasicIdentityStorage.deleteIdentityInfoPromise is only supported for async")));
  598. var thisStorage = this;
  599. var identity = identityName.toUri();
  600. return this.runPromise_
  601. ("DELETE FROM Certificate WHERE identity_name=?", identity)
  602. .then(function() {
  603. return thisStorage.runPromise_("DELETE FROM Key WHERE identity_name=?", identity);
  604. })
  605. .then(function() {
  606. return thisStorage.runPromise_("DELETE FROM Identity WHERE identity_name=?", identity);
  607. });
  608. };
  609. /**
  610. * Retrieve the user's current home directory
  611. * @returns {string} path to the user's home directory
  612. */
  613. BasicIdentityStorage.getUserHomePath = function() {
  614. return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
  615. };
  616. /**
  617. * Call Sqlite3Promise.runPromise, wrapping an Error in SecurityException.
  618. */
  619. BasicIdentityStorage.prototype.runPromise_ = function(sql, params)
  620. {
  621. return this.database_.runPromise(sql, params)
  622. .catch(function(error) {
  623. return Promise.reject(new SecurityException(error));
  624. });
  625. };
  626. /**
  627. * Call Sqlite3Promise.getPromise, wrapping an Error in SecurityException.
  628. */
  629. BasicIdentityStorage.prototype.getPromise_ = function(sql, params)
  630. {
  631. return this.database_.getPromise(sql, params)
  632. .catch(function(error) {
  633. return Promise.reject(new SecurityException(error));
  634. });
  635. };
  636. /**
  637. * Call Sqlite3Promise.eachPromise, wrapping an Error in SecurityException.
  638. */
  639. BasicIdentityStorage.prototype.eachPromise_ = function(sql, params, onRow)
  640. {
  641. return this.database_.eachPromise(sql, params, onRow)
  642. .catch(function(error) {
  643. return Promise.reject(new SecurityException(error));
  644. });
  645. };
  646. /**
  647. * Retrieve the user's current home directory
  648. * @returns {string} path to the user's home directory
  649. */
  650. BasicIdentityStorage.getUserHomePath = function() {
  651. return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
  652. };
  653. BasicIdentityStorage.initializeDatabasePromise_ = function(database)
  654. {
  655. // Check if the ID table exists.
  656. return database.getPromise
  657. ("SELECT name FROM sqlite_master WHERE type='table' And name='Identity'")
  658. .then(function(row) {
  659. if (row)
  660. return Promise.resolve();
  661. else {
  662. return database.runPromise(BasicIdentityStorage.INIT_ID_TABLE1)
  663. .then(function() {
  664. return database.runPromise(BasicIdentityStorage.INIT_ID_TABLE2);
  665. });
  666. }
  667. })
  668. .then(function() {
  669. // Check if the Key table exists.
  670. return database.getPromise
  671. ("SELECT name FROM sqlite_master WHERE type='table' And name='Key'");
  672. })
  673. .then(function(row) {
  674. if (row)
  675. return Promise.resolve();
  676. else {
  677. return database.runPromise(BasicIdentityStorage.INIT_KEY_TABLE1)
  678. .then(function() {
  679. return database.runPromise(BasicIdentityStorage.INIT_KEY_TABLE2);
  680. });
  681. }
  682. })
  683. .then(function() {
  684. // Check if the Certificate table exists.
  685. return database.getPromise
  686. ("SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'");
  687. })
  688. .then(function(row) {
  689. if (row)
  690. return Promise.resolve();
  691. else {
  692. return database.runPromise(BasicIdentityStorage.INIT_CERT_TABLE1)
  693. .then(function() {
  694. return database.runPromise(BasicIdentityStorage.INIT_CERT_TABLE2);
  695. })
  696. .then(function() {
  697. return database.runPromise(BasicIdentityStorage.INIT_CERT_TABLE3);
  698. });
  699. }
  700. });
  701. };
  702. BasicIdentityStorage.INIT_ID_TABLE1 =
  703. "CREATE TABLE IF NOT EXISTS \n" +
  704. " Identity( \n" +
  705. " identity_name BLOB NOT NULL, \n" +
  706. " default_identity INTEGER DEFAULT 0, \n" +
  707. " \n" +
  708. " PRIMARY KEY (identity_name) \n" +
  709. " ); \n" +
  710. " \n";
  711. BasicIdentityStorage.INIT_ID_TABLE2 =
  712. "CREATE INDEX identity_index ON Identity(identity_name); \n";
  713. BasicIdentityStorage.INIT_KEY_TABLE1 =
  714. "CREATE TABLE IF NOT EXISTS \n" +
  715. " Key( \n" +
  716. " identity_name BLOB NOT NULL, \n" +
  717. " key_identifier BLOB NOT NULL, \n" +
  718. " key_type INTEGER, \n" +
  719. " public_key BLOB, \n" +
  720. " default_key INTEGER DEFAULT 0, \n" +
  721. " active INTEGER DEFAULT 0, \n" +
  722. " \n" +
  723. " PRIMARY KEY (identity_name, key_identifier) \n" +
  724. " ); \n" +
  725. " \n";
  726. BasicIdentityStorage.INIT_KEY_TABLE2 =
  727. "CREATE INDEX key_index ON Key(identity_name); \n";
  728. BasicIdentityStorage.INIT_CERT_TABLE1 =
  729. "CREATE TABLE IF NOT EXISTS \n" +
  730. " Certificate( \n" +
  731. " cert_name BLOB NOT NULL, \n" +
  732. " cert_issuer BLOB NOT NULL, \n" +
  733. " identity_name BLOB NOT NULL, \n" +
  734. " key_identifier BLOB NOT NULL, \n" +
  735. " not_before TIMESTAMP, \n" +
  736. " not_after TIMESTAMP, \n" +
  737. " certificate_data BLOB NOT NULL, \n" +
  738. " valid_flag INTEGER DEFAULT 1, \n" +
  739. " default_cert INTEGER DEFAULT 0, \n" +
  740. " \n" +
  741. " PRIMARY KEY (cert_name) \n" +
  742. " ); \n" +
  743. " \n";
  744. BasicIdentityStorage.INIT_CERT_TABLE2 =
  745. "CREATE INDEX cert_index ON Certificate(cert_name); \n";
  746. BasicIdentityStorage.INIT_CERT_TABLE3 =
  747. "CREATE INDEX subject ON Certificate(identity_name); \n";