-
Notifications
You must be signed in to change notification settings - Fork 790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
loading indutny/elliptic library to browser on demand #956
Conversation
987ef8e
to
e2ddb07
Compare
src/build.env.js
Outdated
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
|
||
export default { | ||
use_indutny_elliptic: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, this should be set at runtime instead of compile time, but maybe you don't even need a config option for this. People could just do something like
openpgp.loadElliptic = () => {
throw new Error('Elliptic is not included');
};
Then, you can also remove all the getUseElliptic
checks, as it will automatically throw a useful error when it's trying to load elliptic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This option prevents openpgp from tryng to load elliptic. I think this is useful. For example browserify
has exclude
and external
options. At runtime we could check if elliptic
should be loaded but not loaded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example code I posted would also prevent OpenPGP.js from trying to load elliptic, right? It is a bit more work than passing a flag, but the advantage is that you don't have to create a special build of OpenPGP.js, and that it simplifies OpenPGP.js because we can always just call loadElliptic
before checking first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to substitute function content using grunt replace command? It is not clear for me =).
this.getIndutnyCurve = util.getUseElliptic() ? async name => { | ||
const elliptic = getElliptic() || await loadElliptic(build.external_indutny_elliptic_path); | ||
return new elliptic.ec(name); | ||
} : undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could also put this function in indutnyKey.js - it doesn't use this
, so it doesn't have to be a method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IndutnyKey.js is not public now, I could make it public and move this function here.
e2ddb07
to
0c47a09
Compare
2d94a8c
to
025ecde
Compare
src/config/config.js
Outdated
indutny_elliptic_fetch_options: { | ||
credentials: 'include' | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This default credentials: 'include'
is not necessary, it can be set by the application if needed. You can just default to {}
for the options, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
package.json
Outdated
"tweetnacl": "github:openpgpjs/tweetnacl-js#1ef755f2b252a3e328ac739848d00e0dad76be2d", | ||
"web-stream-tools": "github:openpgpjs/web-stream-tools#dc4b05e8a272b45819233f3df735423432beacfc", | ||
"email-addresses": "github:openpgpjs/email-addresses#686743c6452b44bafcd06d47db7f36ddf3f3f118" | ||
"whatwg-fetch": "^2.0.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty nitpicky, but could you keep these packages in the order they were in? I know they're usually in alphabetic order, but the order they were in was to roughly separate what was needed only for development (everything up to sinon
) and what packages end up in a build (everything starting from text-encoding-utf-8
).
Also, even if you disagree with that, keeping them in the same order in this PR would make it easier to see what changed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Npm kinda do it by itself, once I run npm install elliptic
. May be we could switch to the new ordering convention? It is bothersome to rearrange lines manually after each change, or switching to another git branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May be we could switch to the new ordering convention?
Yeah, we could do that, but preferably not in this PR, since it makes it harder to see what changed.
Once we switch to ES6 modules, we'll move the devDependencies
starting from text-encoding-utf-8
to dependencies
, so then is probably a good time to fix the ordering.
src/lightweight_helper.js
Outdated
script.integrity = integrity; | ||
} | ||
script.onload = e => resolve(e); | ||
script.onerror = e => reject(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
script.onerror = e => reject(e); | |
script.onerror = () => reject(new Error('Failed to load ' + path)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have researched a bit errors that are thrown here, they are network related. This promise would be resolved even if path is wrong, and actually elliptic has failed to load.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example here https://codesandbox.io/s/intelligent-darwin-w9cxx
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. But e
is not an error object, it is an event object. You should throw an error instead of an event. Even for network errors, "failed to load" is pretty descriptive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is actually error event is passed here, I would better catch it in loadEllipticPromise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is an error event, but not an error object. You could do
script.onerror = e => reject(new Error(e.message));
if you prefer, but you should always throw an error object.
src/util.js
Outdated
getUseElliptic: function() { | ||
return config.use_indutny_elliptic; | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this function is really necessary - especially once you're only checking it in one place, you can just check
if (!config.use_indutny_elliptic) {
directly.
Then, in the test suite where you're checking this in a bunch of places, I'm not sure it's really necessary? We're never calling the test suite with config.use_indutny_elliptic = false
, so it should always be available in the test suite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have this function, so I could avoid importing config in bunch of places. I think it is valid use-case.
Regarding tests, since we have option to disable elliptic, let's have test suite which would work with this option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have this function, so I could avoid importing config in bunch of places.
That's why I mentioned "especially once you're only checking it in one place", because then you only have to import config in one place. I don't think that importing util
instead of importing config
is better, when it is config
that you really need to check.
The test suite already uses config
in lots of places, you could search for config
in the test directory to check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
dfdb359
to
f349e96
Compare
combined commits: initial working nodeCrypto ecdh clean up Curve25519 key generation using tweetnacl.js Move KeyPair.sign/verify to ecdsa.js Move KeyPair.derive to ecdh.js fix test, remove deprecated Buffer() add only_constant_time_curves flag to config ecdh is working after refactor ecdsa webVerify is working node signature verify is working without elliptic. sign and verify are working for nodeCrypto use build.config.js renaming to build.env.js fixing KeyPair constructor wip: use grunt for lightweight build add full-build to gruntfile to change from back from lightweight option wip: grunt build --lightweigth is working now refactored use of build.env, fixes ecdsa.sign function WIP: fixed elliptic tests + add throw errors + use switch solve problem with hash streaming using a hack move toHash out of if/else clean up in config and tests for full build chnage travis unit test script clean up reverting changes to worker.min.js moved throw on lightbuild to if move to Array.From in ecdsa add polyfill for Array.from move toHash back to if/else - this would make lightbuild non-functional for streaming remove polyfill array.from, and lightbuild to the gruntfile remove double tests in travis.sh init undutnyKeyPair only on demand. Change KeyPair format. Style fix fixed tests build correctly exclude elliptic in lightweight mode add skiping non-working tests fix gruntfile.js add lightweight tag to tests clean up disabled some tests for lightbuild-webcrypto
We already have util.getFullBuild()
fix jwk key length error load indutny/elliptic on demand in browser context loading elliptic in browser functional WIP new build file, use elliptic lib with prepare script WIP: fix exclude elliptic build WIP: lightweight build with node use correct path WIP copy elliptic.min.js by grunt + almost working static elliptic download WIP eslint fixes add fix option to gruntfile eslint load elliptic to window.openpgp.elliptic add loadElliptic call to tests fix brainpool test
6976196
to
baa68d3
Compare
This was broken in #922 (merged as part of #956). This would cause GPG to be unable to parse unencrypted secret keys, thinking they were encrypted. rfc4880bis-08 hints at this requirement, saying: o MPI of an integer representing the secret key, which is a scalar of the public EC point. Since scalar multiplication happens after masking the private key, this implies that we should serialize the private key after masking, as well.
This was broken in #922 (merged as part of #956). This would cause GPG to be unable to parse unencrypted secret keys, thinking they were encrypted. rfc4880bis-08 hints at this requirement, saying: o MPI of an integer representing the secret key, which is a scalar of the public EC point. Since scalar multiplication happens after masking the private key, this implies that we should serialize the private key after masking, as well.
No description provided.