UNPKG

oidc-lib

Version:

A library for creating OIDC Service Providers

998 lines (869 loc) 27.2 kB
const PERSONALOMNIKEY = 'privateOmniKey'; const INTEGRITYKEY = 'integrityKey'; const STS_MODULENAME = 'sts'; const PERSONAKEY = 'personaKey'; const PAIRWISEKEY = 'pairwiseKey'; const KEY_EXTRACTABLE = true; var contentModuleSigningKeys = {}; var contentModuleSigningKeystores = {}; var contentModuleSigningKeysPublic = {}; var contentModuleSigningKids = {}; var contentModuleIntegrityKeys = {}; var contentModuleIntegrityKeystores = {}; var pk; function registerEndpoints(pkInput){ pk = pkInput; } async function createOrLoadSingleKey(keyObject){ var dbInfo = pk.dbs[STS_MODULENAME]; var keyObjectArray; var error_message; try{ // if no db is defined the key object will be missing key values if (dbInfo === undefined){ error_message = ''; throw('no database is defined in createOrLoadSingleKey'); } var target = { content_module_name: keyObject.content_module_name, app_id: keyObject.app_id }; if (keyObject.app_role){ target.app_role = keyObject.app_role; } if (keyObject.creation_date){ target.creation_date = keyObject.creation_date; } if (keyObject.kid){ target.kid = keyObject.kid; } if (keyObject.did){ target.did = keyObject.did; } var error_message = '[ClientLib] Error querying keys - ' + koDisplayName(keyObject); var keyObjectArray = await dbInfo.provider.queryCollection(dbInfo, 'keys', target); var error_message = 'Error creating single key'; if (keyObject.renew === true || keyObjectArray.length === 0){ var createdKey = await createSingleKey(dbInfo, keyObject); console.log('A new key was created:', JSON.stringify(createdKey, null, 4) + '\r\n'); keyObjectArray.push(createdKey); } var error_message = 'Error in keyObjectArrayToKeyAndStore'; var keyAndStore = await keyObjectArrayToKeyAndStore(keyObjectArray); pk.util.log_debug('[ClientLib] Success loading keystore - ' + koDisplayName(keyObject)); return keyAndStore; } catch(err){ pk.util.log_error('createOrLoadSingleKey','Error in createOrLoadSingleKey', err); throw ('Error in createOrLoadSingleKey: ' + err); } } async function keyObjectArrayToKeyAndStore(keyObjects){ var newestKeyObject; var publicKeys = { keys: [] }; var latestTime = 0; for (var i=0; i<keyObjects.length; i++){ var keyObject = keyObjects[i]; if (keyObject.public !== undefined){ publicKeys.keys.push(keyObject.public); } if (keyObject.creation_date > latestTime){ newestKeyObject = keyObject; latestTime = keyObject.creation_date; } } try{ var loadedKeyStore = await pk.claimer_crypto.JWK.asKeyStore(keyObjects); var keyAndStore = { 'store': loadedKeyStore, 'keyObject': newestKeyObject, 'publicKeyStore': publicKeys }; return(keyAndStore); } catch(err){ pk.util.log_detail("Error loading keystore", err); throw("Error loading keystore"); } } async function createSingleKey(dbInfo, keyObject){ if (pk.claimer_crypto.provider === 'node-jose'){ return await createSingleKey_nodejs(dbInfo, keyObject) } else { return await createSingleKey_webCryptoApi(dbInfo, keyObject) } } async function createSingleKey_webCryptoApi(dbInfo, keyObject){ var error_message; try{ var date = new Date(); if (keyObject.creation_date === undefined){ keyObject.creation_date = date.getTime(); } switch (keyObject.alg){ case "RS256": var w3c_rsa_algorithm = { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: { name: "SHA-256" } }; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } error_message = "RS256 key creation error: "; var keyPair = await crypto.subtle.generateKey(w3c_rsa_algorithm, KEY_EXTRACTABLE, keyObject.key_ops) keyObject.private = keyPair.privateKey; keyObject.public = keyPair.publicKey; error_message = 'RS256 public key export error: '; var exportedPublic = await crypto.subtle.exportKey("jwk", keyPair.publicKey); keyObject.jwk_public = exportedPublic; if (keyPair.privateKey.extractable){ error_message = 'RS256 private key export error: '; var exportedPrivate = await crypto.subtle.exportKey("jwk", keyPair.privateKey); keyObject.jwk_private = exportedPrivate; } error_message = 'RS256 kid could not be calculated: '; var kidAsPerSpec = await pk.simple_crypto.jwkThumbprint(exportedPublic); keyObject.kid = pk.util.randomToURN(kidAsPerSpec); keyObject.id = keyObject.kid; error_message = 'RS256 key storage error : '; break; case "ECDSA": var crv = keyObject.crv ? keyObject.crv : 'P-256'; var ecdsa_algorithm = { name: "ECDSA", crv: crv // subtle crypto requires 'namedCurve' }; var subtle_ecdsa_algorithm = { name: "ECDSA", namedCurve: crv // subtle crypto requires 'namedCurve' } if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } error_message = "ECDSA key creation error: "; var keyPair = await crypto.subtle.generateKey(subtle_ecdsa_algorithm, KEY_EXTRACTABLE, keyObject.key_ops) keyObject.private = keyPair.privateKey; keyObject.public = keyPair.publicKey; error_message = 'ECDSA public key export error: '; var exportedPublic = await crypto.subtle.exportKey("jwk", keyPair.publicKey); keyObject.jwk_public = exportedPublic; if (keyPair.privateKey.extractable){ error_message = 'ECDSA private key export error: '; var exportedPrivate = await crypto.subtle.exportKey("jwk", keyPair.privateKey); keyObject.jwk_private = exportedPrivate; } error_message = 'ECDSA kid could not be calculated: '; var kidAsPerSpec = await pk.simple_crypto.jwkThumbprint(exportedPublic); keyObject.kid = kidAsPerSpec; keyObject.id = keyObject.kid; error_message = 'ECDSA key storage error : '; break; case "EdDSA": var crv = keyObject.crv ? keyObject.crv : 'Ed25519'; var ed25519_algorithm = { name: "EdDSA", crv: crv }; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } error_message = "ed25519_algorithm key creation error: "; var ed25519 = forge.pki.ed25519; var keyPair = ed25519.generateKeyPair(); keyObject.private = { algorithm: ed25519_algorithm, extractable: true, type: "private", usages: ["sign"], key: keyPair.privateKey }; keyObject.public = { algorithm: ed25519_algorithm, extractable: true, type: "public", usages: ["verify"], key: keyPair.publicKey }; error_message = 'EdDSA public key export error: '; // SHOULD x be base64 encoded or base58 encoded????? keyObject.jwk_public = { "kty" : "OKP", "crv" : "Ed25519", "x" : pk.base64url.encode(keyPair.publicKey), "use" : "sig", } error_message = 'EdDSA private key export error: '; // SHOULD x be base64 encoded or base58 encoded????? keyObject.jwk_private = { "kty" : "OKP", "crv" : "Ed25519", 'd': pk.base64url.encode(keyPair.privateKey), "x" : pk.base64url.encode(keyPair.publicKey), "use" : "sig", } error_message = 'EdDSA kid could not be calculated: '; var kidAsPerSpec = await pk.simple_crypto.jwkThumbprint(keyObject.jwk_public); keyObject.kid = kidAsPerSpec; keyObject.jwk_public.kid = keyObject.kid; keyObject.id = keyObject.kid; break; case "RSA-OAEP": var w3c_rsa_algorithm = { name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: { name: "SHA-256" } }; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify', 'encrypt', 'decrypt']; } error_message = "RSA-OAEP key creation error: "; var keyPair = await crypto.subtle.generateKey(w3c_rsa_algorithm, KEY_EXTRACTABLE, keyObject.key_ops) keyObject.private = keyPair.privateKey; keyObject.public = keyPair.publicKey; error_message = 'RSA-OAEP public key export error: ' var exportedPublic = await crypto.subtle.exportKey("jwk", keyPair.publicKey); keyObject.jwk_public = exportedPublic; if (keyPair.privateKey.extractable){ error_message = 'RSA_OAEP private key export error: '; var exportedPrivate = await crypto.subtle.exportKey("jwk", keyPair.privateKey); keyObject.jwk_private = exportedPrivate; } error_message = 'RSA-OAEP kid could not be calculated: '; var kid = await pk.simple_crypto.jwkThumbprint(exportedPublic); keyObject.kid = pk.util.randomToURN(kid); keyObject.id = keyObject.kid; error_message = 'RSA-OAEP key storage error : '; break; case "A128GCM": var w3c_aes_algorithm = { name: "AES-GCM", length: 128 }; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['encrypt', 'decrypt']; } error_message = 'AES key could not be generated: '; var newAesKey = await crypto.subtle.generateKey(w3c_aes_algorithm, KEY_EXTRACTABLE, ['encrypt', 'decrypt']); keyObject.kid = keyObject.creation_date.toString(); keyObject.id = keyObject.kid; keyObject.symmetric = newAesKey; if (newAesKey.extractable){ error_message = 'A128GCM key export error: '; var exportedSymmetric = await crypto.subtle.exportKey("jwk", newAesKey); keyObject.jwk_symmetric = exportedSymmetric; } error_message = 'symmetric key was not stored as expected: '; break; default: throw ('undefined key algorithm in createSingleKey_webCryptoApi'); } if (dbInfo){ var confirmation = await pk.dbs.sts.provider.createOrUpdateDocument( pk.dbs.sts, 'keys', keyObject, null); } return (keyObject); } catch(err){ throw (error_message + err); } } async function createSingleKey_nodejs(dbInfo, keyObject){ var error_message; try{ var date = new Date(); var keystore = pk.claimer_crypto.JWK.createKeyStore(); if (keyObject.creation_date === undefined){ keyObject.creation_date = date.getTime(); } switch (keyObject.alg){ case "RS256": if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } var genParams = { alg: keyObject.alg, use: 'sig' }; error_message = 'RS256 kid could not be calculated '; var result = await keystore.generate("RSA", 2048, genParams); keyObject.kid = keyObject.kid ? keyObject.kid : pk.util.randomToURN(result.kid); keyObject.private = keystore.toJSON(true).keys[0]; keyObject.private.kid = pk.util.randomToURN(keyObject.private.kid); keyObject.public = keystore.toJSON().keys[0]; keyObject.public.kid = pk.util.randomToURN(keyObject.public.kid); keyObject.jwk_public = keyObject.public; keyObject.id = result.kid; error_message = 'keyObject was not stored as expected '; break; case "ECDSA": var curve = keyObject.crv ? keyObject.crv : 'P-256'; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } var genParams = { alg: keyObject.alg, use: 'sig' }; error_message = 'EC kid could not be calculated '; var result = await keystore.generate("EC", curve, genParams); var jwk = result.toJSON(false); keyObject.kid = keyObject.kid ? keyObject.kid : pk.util.randomToURN(result.kid); keyObject.private = keystore.toJSON(true).keys[0]; keyObject.private.kid = pk.util.randomToURN(keyObject.private.kid); keyObject.public = keystore.toJSON().keys[0]; keyObject.public.kid = pk.util.randomToURN(keyObject.public.kid); keyObject.jwk_public = keyObject.public; keyObject.id = result.kid; error_message = 'keyObject was not stored as expected '; break; case "EdDSA": var crv = keyObject.crv ? keyObject.crv : 'Ed25519'; var ed25519_algorithm = { name: "EdDSA", crv: crv }; if (keyObject.key_ops === undefined){ keyObject.key_ops = ['sign', 'verify']; } error_message = "ed25519_algorithm key creation error: "; var ed25519 = pk.forge.pki.ed25519; var keyPair = ed25519.generateKeyPair(); keyObject.private = { algorithm: ed25519_algorithm, extractable: true, type: "private", usages: ["sign"], key: keyPair.privateKey }; keyObject.public = { algorithm: ed25519_algorithm, extractable: true, type: "public", usages: ["verify"], key: keyPair.publicKey }; error_message = 'EdDSA public key export error: '; // SHOULD x be base64 encoded or base58 encoded????? keyObject.jwk_public = { "kty" : "OKP", "crv" : "Ed25519", "x" : pk.base64url.encode(keyPair.publicKey), "use" : "sig" } error_message = 'EdDSA kid could not be calculated: '; var kidAsPerSpec = await pk.simple_crypto.jwkThumbprint(keyObject.jwk_public); keyObject.kid = kidAsPerSpec; keyObject.jwk_public.kid = kidAsPerSpec; keyObject.id = keyObject.kid; break; case "A128GCM": if (keyObject.key_ops === undefined){ keyObject.key_ops = ['encrypt', 'decrypt']; } var genParams = { alg: keyObject.alg, use: 'enc', kid: keyObject.creation_date.toString() }; error_message = 'AES key could not be generated: '; await keystore.generate("oct", 128, genParams); keyObject.kid = keyObject.kid ? keyObject.kid : keyObject.creation_date.toString(); keyObject.jwk_public = keystore.toJSON(true); if (pk.claimer_crypto.provider === 'node-jose'){ keyObject.id = keyObject.kid; } else{ keyObject.id = keyObject.keyPath; } keyObject.symmetric = keyObject.jwk_public.keys[0]; break; default: break; } if (dbInfo){ await dbInfo.provider.createOrUpdateDocument( dbInfo, 'keys', keyObject, null); } return(keyObject); } catch(err){ throw(error_message + err); } } function claimerKeyObject(content_module_name, app_id, ktyOrKeyParams, alg, crv) { var _content_module_name = content_module_name; var _app_id = app_id; var _app_role; var _kid; var _key_ops; var _creation_date; var _private; var _public; var _symmetric; var _jwk_public; var _jwk_private; var _jwk_symmetric; var _keyParams; var _renew; var _did; var _id; // database id if (typeof ktyOrKeyParams === 'string'){ _keyParams = pk.wallet_key_types.getKeyParams( { kty: ktyOrKeyParams, alg: alg, crv: crv }); } else{ _keyParams = ktyOrKeyParams; } Object.defineProperty(this, "content_module_name", { get: function() { return _content_module_name; }, set: function(newValue){ _content_module_name = newValue; }, enumerable: true }); Object.defineProperty(this, "app_id", { get: function() { return _app_id; }, set: function(newValue){ _app_id = newValue; }, enumerable: true }); Object.defineProperty(this, "app_role", { get: function() { return _app_role; }, set: function(newValue){ _app_role = newValue; }, enumerable: true }); Object.defineProperty(this, "kty", { get: function() { return _keyParams.kty; }, set: function(newValue){ _keyParams.kty = newValue; }, enumerable: true }); Object.defineProperty(this, "alg", { get: function() { return _keyParams.alg; }, set: function(newValue){ _keyParams.alg = newValue; }, enumerable: true }); Object.defineProperty(this, "crv", { get: function() { return _keyParams.crv; }, set: function(newValue){ _keyParams.crv = newValue; }, enumerable: true }); Object.defineProperty(this, "multicodec_bytes", { get: function() { return _keyParams.multicodec_bytes; }, set: function(newValue){ _keyParams.multicodec_bytes = newValue; }, enumerable: true }); Object.defineProperty(this, "signature_alg", { get: function() { return _keyParams.signature_alg; }, set: function(newValue){ _keyParams.signature_alg = newValue; }, enumerable: true }); Object.defineProperty(this, "kid", { get: function() { return _kid; }, set: function(newValue){ _kid = newValue; }, enumerable: true }); Object.defineProperty(this, "did", { get: function() { return _did; }, set: function(newValue){ _did = newValue; }, enumerable: true }); Object.defineProperty(this, "key_ops", { get: function() { return _key_ops; }, set: function(newValue){ _key_ops = newValue; }, enumerable: true }); Object.defineProperty(this, "creation_date", { get: function() { return _creation_date; }, set: function(newValue){ _creation_date = newValue; }, enumerable: true }); Object.defineProperty(this, "private", { get: function() { return _private; }, set: function(newValue){ _private = newValue; }, enumerable: true }); Object.defineProperty(this, "public", { get: function() { return _public; }, set: function(newValue){ _public = newValue; }, enumerable: true }); Object.defineProperty(this, "symmetric", { get: function() { return _symmetric; }, set: function(newValue){ _symmetric = newValue; }, enumerable: true }); Object.defineProperty(this, "jwk_private", { get: function() { return _jwk_private; }, set: function(newValue){ _jwk_private = newValue; }, enumerable: true }); Object.defineProperty(this, "jwk_public", { get: function() { return _jwk_public; }, set: function(newValue){ _jwk_public = newValue; }, enumerable: true }); Object.defineProperty(this, "jwk_symmetric", { get: function() { return _jwk_symmetric; }, set: function(newValue){ _jwk_symmetric = newValue; }, enumerable: true }); Object.defineProperty(this, "renew", { get: function() { return _renew; }, set: function(newValue){ _renew = newValue; }, enumerable: true, configurable: true }); Object.defineProperty(this, "id", { get: function() { return _id; }, set: function(newValue){ _id = newValue; }, enumerable: true, configurable: true }); } function clientGetProperty(client_id, propertyName) { var client = clientInfo[client_id]; if (client === undefined){ throw "Invalid Client"; } return client[propertyName]; } async function loadSingleKey(keyObjectOrId, props){ var dbInfo = pk.dbs[STS_MODULENAME]; var keyObjectArray; var potentialError = ''; try { // if no db is defined the key object will be missing key values if (dbInfo === undefined){ resolve(null); return; } if (typeof keyObjectOrId === 'string'){ var keyId = keyObjectOrId; potential_error = 'Error retrieving key id: ' + keyId; var retrievedKeyObject = await dbInfo.provider.getDocument(dbInfo, 'keys', keyId); keyObjectArray = [ retrievedKeyObject ]; } else if (keyObjectOrId.index) { potential_error = 'Error retrieving indexed key id: ' + keyId; var retrievedKeyObject = await dbInfo.provider.getDocument(dbInfo, 'keys', keyObjectOrId.index, keyObjectOrId.value); keyObjectArray = [ retrievedKeyObject ]; } else if (keyObjectOrId.dictionary) { potential_error = 'Error retrieving key via dictionary: ' + JSON.stringify(keyObjectOrId.dictionary, null, 4) + '\r\n'; var keyObjectArray = await dbInfo.provider.queryCollection(dbInfo, 'keys', keyObjectOrId.dictionary); if (keyObjectArray.length === 0){ throw ('dictionary produced no key collection'); } } else{ var keyObject = keyObjectOrId; var target = { content_module_name: keyObject.content_module_name, app_id: keyObject.app_id }; if (keyObject.app_role){ target.app_role = keyObject.app_role; } if (props){ for (var k in props){ target[k] = props[k]; } } potential_error = '[ClientLib] Error querying key collection'; keyObjectArray = await dbInfo.provider.queryCollection(dbInfo, 'keys', target); if (keyObjectArray.length === 0){ throw ('[ClientLib] key collection returns empty'); } } potential_error = '[ClientLib] Error querying keys'; var keyAndStore = await keyObjectArrayToKeyAndStore(keyObjectArray); pk.util.log_debug('[ClientLib] Success loading keystore'); return keyAndStore; } catch(err){ throw ('Error in loadSingleKey: ' + potential_error + ' - ' + err); } } async function updateSingleKey(keyObject, properties){ var potential_error; try{ var dbInfo = pk.dbs[STS_MODULENAME]; var potential_error = '[UpdateSingleKey] Error querying keys'; var keyAndStore = await loadSingleKey(keyObject); var keyObj = keyAndStore.keyObject; for (var key in properties){ keyObj[key] = properties[key]; } var result = await dbInfo.provider.createOrUpdateDocument( dbInfo, 'keys', keyObj, null); return result; } catch(err){ throw(err); } } function koDisplayName(keyObject){ return keyObject.content_module_name + ':' + keyObject.app_id + (keyObject.app_role ? ':' + keyObject.app_role : ''); } async function loadOrCreateKeys() { try { var keysRequired = []; for (var moduleName in pk.feature_modules){ if (!pk.feature_modules[moduleName].code.invokeConsentUserAgent){ continue; } var omniKeyObj = new pk.key_management.claimerKeyObject(moduleName, pk.key_management.PERSONALOMNIKEY, "RSA", "RS256"); var omniKeyAndStore = await createOrLoadSingleKey(omniKeyObj); connectKeyToContentModule(omniKeyAndStore); var integrityKeyObj = new pk.key_management.claimerKeyObject(moduleName, pk.key_management.INTEGRITYKEY, "oct", "A128GCM"); var integrityKeyAndStore = await createOrLoadSingleKey(integrityKeyObj); connectKeyToContentModule(integrityKeyAndStore); } } catch(err){ } } function connectKeyToContentModule(keyAndStore){ if (keyAndStore !== null){ var keyObject = keyAndStore.keyObject; switch (keyObject.alg){ case "RS256": contentModuleSigningKeys[keyObject.content_module_name] = keyObject; contentModuleSigningKeystores[keyObject.content_module_name] = keyAndStore.store; contentModuleSigningKids[keyObject.content_module_name] = keyObject.kid; contentModuleSigningKeysPublic[keyObject.content_module_name] = keyAndStore.publicKeyStore; break; case "A128GCM": contentModuleIntegrityKeys[keyObject.content_module_name] = keyObject; contentModuleIntegrityKeystores[keyObject.content_module_name] = keyAndStore.store; break; default: alert("Unrecognized key alg in connectKeysToContentModule: " + keyObject.alg); return; } } } function signatureAlg(keyObj){ var sigAlg; switch (keyObj.alg){ case 'RS256': sigAlg = 'RS256'; break; case 'ECDSA': switch (keyObj.crv){ case 'P-256': sigAlg = 'ES256'; break; case 'P-384': sigAlg = 'ES384'; break; case 'P-512': sigAlg = 'ES512'; break; default: throw ('Invalid Named crv getting signatureAlg: ' + keyObj.crv); } break; case 'EdDSA': sigAlg = 'EdDSA'; break; default: throw('signatureAlg not defined for ' + keyObj.alg); } return sigAlg; } function expandValidKeyType(keyType){ return pk.wallet_key_types.getKeyParams(keyType); } function testKeyTypes(){ // returning keyType var a = pk.wallet_key_types.keyKeyParams({ alg: 'RS256' }); a = pk.wallet_key_types.keyKeyParams({ alg: 'RS256', kty: 'RSA' }); a = pk.wallet_key_types.keyKeyParams({ alg: 'ECDSA', kty: 'EC' }); a = pk.wallet_key_types.keyKeyParams({ alg: 'ECDSA', kty: 'EC', crv: 'P-384' }); a = pk.wallet_key_types.keyKeyParams({ multicodec: [ 0x12, 0x02] }); var multicodec_bytes = a.multicodec_bytes; a = pk.wallet_key_types.keyKeyParams({ multicodec_bytes: multicodec_bytes }); // returning undefined a = pk.wallet_key_types.keyKeyParams({ alg: 'RSA' }); } // used when importing keys into index_db async function keyObjectImportKey(dbName, collectionName, record){ var fixup; if (dbName === 'sts' && collectionName === 'keys'){ var algorithm; var cryptoKeyStorage; var key_usages; switch (record.alg){ case 'A128GCM': algorithm = { name: 'AES-GCM' }; cryptoKeyStorage = 'symmetric'; key_usages = [ 'encrypt', 'decrypt']; break; case 'RS256': key_usages = [ 'sign']; cryptoKeyStorage = 'private' algorithm = { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256'}; break; case 'RSA-OAEP': algorithm = { name: 'RSA-OAEP', hash: 'SHA-256'}; cryptoKeyStorage = 'private' key_usages = [ 'encrypt']; break; case 'ECDSA': key_usages = [ 'sign']; cryptoKeyStorage = 'private' algorithm = { name: 'ECDSA', namedCurve: record.jwk_private.crv }; break; default: return; } const result = await crypto.subtle.importKey( 'jwk', record['jwk_' + cryptoKeyStorage], algorithm, true, key_usages ); if (record.multicodec_bytes){ if (typeof record.multicodec_bytes === 'object'){ var len = Object.keys(record.multicodec_bytes).length; var uint8Array = new Uint8Array(len); var c = 0; for (var el in record.multicodec_bytes){ uint8Array[c++] = record.multicodec_bytes[el]; } record.multicodec_bytes = uint8Array; } } fixup = record; fixup[cryptoKeyStorage] = result; return fixup; } } module.exports = { registerEndpoints: registerEndpoints, loadOrCreateKeys: loadOrCreateKeys, createSingleKey: createSingleKey, createOrLoadSingleKey: createOrLoadSingleKey, claimerKeyObject: claimerKeyObject, loadSingleKey: loadSingleKey, updateSingleKey: updateSingleKey, signatureAlg: signatureAlg, PERSONALOMNIKEY: PERSONALOMNIKEY, INTEGRITYKEY: INTEGRITYKEY, PERSONAKEY: PERSONAKEY, PAIRWISEKEY: PAIRWISEKEY, contentModuleSigningKeys: contentModuleSigningKeys, contentModuleSigningKeystores: contentModuleSigningKeystores, contentModuleSigningKeysPublic: contentModuleSigningKeysPublic, contentModuleSigningKids: contentModuleSigningKids, contentModuleIntegrityKeys: contentModuleIntegrityKeys, contentModuleIntegrityKeystores: contentModuleIntegrityKeystores, expandValidKeyType: expandValidKeyType, keyObjectImportKey: keyObjectImportKey };