aboutsummaryrefslogtreecommitdiffstats
path: root/lang/js/src/Key.js
diff options
context:
space:
mode:
Diffstat (limited to 'lang/js/src/Key.js')
-rw-r--r--lang/js/src/Key.js244
1 files changed, 244 insertions, 0 deletions
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
new file mode 100644
index 00000000..075a190e
--- /dev/null
+++ b/lang/js/src/Key.js
@@ -0,0 +1,244 @@
+/* gpgme.js - Javascript integration for gpgme
+ * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+
+/**
+ * The key class allows to query the information defined in gpgme Key Objects
+ * (see https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
+ *
+ * This is a stub, as the gpgme-json side is not yet implemented
+ *
+ */
+
+import { isFingerprint } from './Helpers'
+import { gpgme_error } from './Errors'
+import { createMessage } from './Message';
+import { permittedOperations } from './permittedOperations';
+import { Connection } from './Connection';
+
+
+export function createKey(fingerprint, parent){
+ if (!isFingerprint(fingerprint)){
+ return gpgme_error('PARAM_WRONG');
+ }
+ if ( parent instanceof Connection){
+ return new GPGME_Key(fingerprint, parent);
+ } else if ( parent.hasOwnProperty('connection') &&
+ parent.connection instanceof Connection){
+ return new GPGME_Key(fingerprint, parent.connection);
+ } else {
+ return gpgme_error('PARAM_WRONG');
+ }
+}
+
+export class GPGME_Key {
+
+ constructor(fingerprint, connection){
+ this.fingerprint = fingerprint;
+ this.connection = connection;
+ }
+
+ set connection(conn){
+ if (this._connection instanceof Connection) {
+ gpgme_error('CONN_ALREADY_CONNECTED');
+ } else if (conn instanceof Connection ) {
+ this._connection = conn;
+ }
+ }
+
+ get connection(){
+ if (!this._fingerprint){
+ return gpgme_error('KEY_INVALID');
+ }
+ if (!this._connection instanceof Connection){
+ return gpgme_error('CONN_NO_CONNECT');
+ } else {
+ return this._connection;
+ }
+ }
+
+ set fingerprint(fpr){
+ if (isFingerprint(fpr) === true && !this._fingerprint){
+ this._fingerprint = fpr;
+ }
+ }
+
+ get fingerprint(){
+ if (!this._fingerprint){
+ return gpgme_error('KEY_INVALID');
+ }
+ return this._fingerprint;
+ }
+
+ /**
+ * hasSecret returns true if a secret subkey is included in this Key
+ */
+ get hasSecret(){
+ return this.checkKey('secret');
+ }
+
+ get isRevoked(){
+ return this.checkKey('revoked');
+ }
+
+ get isExpired(){
+ return this.checkKey('expired');
+ }
+
+ get isDisabled(){
+ return this.checkKey('disabled');
+ }
+
+ get isInvalid(){
+ return this.checkKey('invalid');
+ }
+
+ get canEncrypt(){
+ return this.checkKey('can_encrypt');
+ }
+
+ get canSign(){
+ return this.checkKey('can_sign');
+ }
+
+ get canCertify(){
+ return this.checkKey('can_certify');
+ }
+
+ get canAuthenticate(){
+ return this.checkKey('can_authenticate');
+ }
+
+ get isQualified(){
+ return this.checkKey('is_qualified');
+ }
+
+ get armored(){
+ let msg = createMessage ('export_key');
+ msg.setParameter('armor', true);
+ if (msg instanceof Error){
+ return gpgme_error('KEY_INVALID');
+ }
+ this.connection.post(msg).then(function(result){
+ return result.data;
+ });
+ // TODO return value not yet checked. Should result in an armored block
+ // in correct encoding
+ }
+
+ /**
+ * TODO returns true if this is the default key used to sign
+ */
+ get isDefault(){
+ throw('NOT_YET_IMPLEMENTED');
+ }
+
+ /**
+ * get the Key's subkeys as GPGME_Key objects
+ * @returns {Array<GPGME_Key>}
+ */
+ get subkeys(){
+ return this.checkKey('subkeys').then(function(result){
+ // TBD expecting a list of fingerprints
+ if (!Array.isArray(result)){
+ result = [result];
+ }
+ let resultset = [];
+ for (let i=0; i < result.length; i++){
+ let subkey = new GPGME_Key(result[i], this.connection);
+ if (subkey instanceof GPGME_Key){
+ resultset.push(subkey);
+ }
+ }
+ return Promise.resolve(resultset);
+ }, function(error){
+ //TODO this.checkKey fails
+ });
+ }
+
+ /**
+ * creation time stamp of the key
+ * @returns {Date|null} TBD
+ */
+ get timestamp(){
+ return this.checkKey('timestamp');
+ //TODO GPGME: -1 if the timestamp is invalid, and 0 if it is not available.
+ }
+
+ /**
+ * The expiration timestamp of this key TBD
+ * @returns {Date|null} TBD
+ */
+ get expires(){
+ return this.checkKey('expires');
+ // TODO convert to Date; check for 0
+ }
+
+ /**
+ * getter name TBD
+ * @returns {String|Array<String>} The user ids associated with this key
+ */
+ get userIds(){
+ return this.checkKey('uids');
+ }
+
+ /**
+ * @returns {String} The public key algorithm supported by this subkey
+ */
+ get pubkey_algo(){
+ return this.checkKey('pubkey_algo');
+ }
+
+ /**
+ * generic function to query gnupg information on a key.
+ * @param {*} property The gpgme-json property to check.
+ * TODO: check if Promise.then(return)
+ */
+ checkKey(property){
+ if (!this._fingerprint){
+ return gpgme_error('KEY_INVALID');
+ }
+ return gpgme_error('NOT_YET_IMPLEMENTED');
+ // TODO: async is not what is to be ecpected from Key information :(
+ if (!property || typeof(property) !== 'string' ||
+ !permittedOperations['keyinfo'].hasOwnProperty(property)){
+ return gpgme_error('PARAM_WRONG');
+ }
+ let msg = createMessage ('keyinfo');
+ if (msg instanceof Error){
+ return gpgme_error('PARAM_WRONG');
+ }
+ msg.setParameter('fingerprint', this.fingerprint);
+ this.connection.post(msg).then(function(result, error){
+ if (error){
+ return gpgme_error('GNUPG_ERROR',error.msg);
+ } else if (result.hasOwnProperty(property)){
+ return result[property];
+ }
+ else if (property == 'secret'){
+ // TBD property undefined means "not true" in case of secret?
+ return false;
+ } else {
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
+ }
+ }, function(error){
+ return gpgme_error('GENERIC_ERROR');
+ });
+ }
+}; \ No newline at end of file