Skip to content
This repository has been archived by the owner on Aug 5, 2024. It is now read-only.

Private key can't be used as-is when downloaded #81

Closed
leggetter opened this issue Jul 22, 2016 · 17 comments
Closed

Private key can't be used as-is when downloaded #81

leggetter opened this issue Jul 22, 2016 · 17 comments
Labels

Comments

@leggetter
Copy link
Contributor

If you try to use the private key when it's downloaded, upon signing you are likely to get an error:

asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

If you're seeing errors such as asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag then you should run the following on your key.txt:

openssl rsa -in key.txt -out key.txt

It may be that there are newline characters in the downloaded file that need to be stripped. Or some other set of characters. I've been informed that it's newline characters, but I haven't checked.

@leggetter leggetter added the bug label Jul 22, 2016
@cbetta
Copy link
Contributor

cbetta commented Jul 23, 2016

Please can you list the actual problem? I don't think that proposed solution does what you think it does. As it stands that openssl command throws the same error as you described, wether there's a trailing space, no trailing space, wether I saved the file myself or let the nexmo CLi save the file, etc.

Additionally I am able to generate a public key off the private key using: ssh-keygen -y -e -f private.key suggesting the key is not in a bad format.

What command is failing for you?

@cbetta
Copy link
Contributor

cbetta commented Aug 24, 2016

@leggetter any update on this?

@leggetter
Copy link
Contributor Author

No. Will provide details when we get to a tutorial that requires a workflow
that demonstrates it.

On Wed, 24 Aug 2016, 09:19 Cristiano Betta, notifications@github.com
wrote:

@leggetter https://github.com/leggetter any update on this?


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#81 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAUCr8KbaW4HMtr-vgry5MExf0g74La9ks5qi_6ggaJpZM4JTJ1q
.

@cbetta cbetta added blocked and removed bug labels Aug 24, 2016
@leggetter
Copy link
Contributor Author

leggetter commented Aug 24, 2016

Steps to reproduce:

1. Create an App and save the private key

nexmo app:create outbound-ex https://voice.ngrok.io/answer https://voice.ngrok.io/event --keyfile private.key

2. Attempt to create a JWT

Below APPLICATION_ID is the created application ID. PRIVATE_KEY_FILE is the name of the key file and is expected to be in the parent directory.

var fs = require('fs');
var uuid = require('node-uuid');
var jwt = require('jsonwebtoken');

function sign(cert, applicationId) {
  var toSign = {
    'iat': Date.now(),
        'application_id': applicationId,
         "jti": uuid.v1()
    };

  var token = jwt.sign(toSign, cert, {algorithm: 'RS256'});
  return token;
}

var key = fs.readFileSync(__dirname + '/../' + PRIVATE_KEY_FILE);
var token = sign(key, APPLICATION_ID);

When executing the above code you'll see the error similar to:

crypto.js:276
  var ret = this._handle.sign(toBuf(key), null, passphrase);
                         ^

Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
    at Error (native)
    at Sign.sign (crypto.js:276:26)
    at Object.sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jwa/index.js:54:45)
    at Object.jwsSign [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jws/lib/sign-stream.js:23:24)
    at Object.module.exports [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jsonwebtoken/sign.js:144:16)
    at sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:20:19)
    at Object.<anonymous> (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:25:13)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)

3. Fix the Key File

To fix this you need to modify the keyfile:

› openssl rsa -in private.key -out private.key
writing RSA key

4. Run the same code. No error.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

@leggetter is this signing process documented somewhere? Would love to reimplement in Ruby just to ensure it's not a Node issue.

Also: this signing doesn't actually make any API calls. After you fix the key and sign the token, does the API accept the signature?

@leggetter
Copy link
Contributor Author

leggetter commented Aug 25, 2016

@cbetta There's a Ruby example on this page https://docs.nexmo.com/voice/voice-api#first_call

The API calls do succeed after fixing the key, yes.

It could be a Node thing. Although I think @sammachin suggested he'd seen a problem with Python too.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

@leggetter followed the Ruby example and signing just works...

Going to try the Node sample next to ensure that it fails here.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

Error confirmed. Interestingly the conversion you suggested throws the following error here:

unable to load Private Key
34783:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/crypto/asn1/tasn_dec.c:1344:
34783:error:0D06C03A:asn1 encoding routines:ASN1_D2I_EX_PRIMITIVE:nested asn1 error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/crypto/asn1/tasn_dec.c:848:
34783:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/crypto/asn1/tasn_dec.c:768:Field=n, Type=RSA
34783:error:0D09A00D:asn1 encoding routines:d2i_PrivateKey:ASN1 lib:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/crypto/asn1/d2i_pr.c:99:
34783:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/crypto/pem/pem_pkey.c:125:

@leggetter
Copy link
Contributor Author

@cbetta that looks like it can't find the file.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

@leggetter it's most certainly there.

I noticed something else interesting:

I ran the app creation command without saving the key to file. I then copy pasted the key to a new file myself. I then re-ran the JS code and got the same error. This seems to suggest it's not an issue with the Node CLI but a deeper issue with either the key, or the JS code loading the key. Am I wrong?

@leggetter
Copy link
Contributor Author

@leggetter it's most certainly there.

Are you sure? Kidding! 😄

What if you run the Ruby code on the copied key? I'm wondering if it is Node specific handling of some sort of encoding.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

@leggetter no issue in Ruby.

Could you do me a favor and try the same? Skip the CLI, make an API call using CURL or the Node lib, save the key to file yourself, and then run the Node command on it. If it fails at this point we need to probably look at the cert returned by the API, or at the correct way to load the key in Node.

I tried making it work in Python but I keep getting ImportError: No module named Crypto.Hash.SHA256 even though I have the crypto module installed.

@cbetta
Copy link
Contributor

cbetta commented Aug 25, 2016

I managed to make the Python sample work (reinstall pycrypto which is not even listed as a dependency) and it works fine!

@leggetter
Copy link
Contributor Author

  1. Make a CURL request to create the app:
base_url='https://api.nexmo.com'
  version='/beta'
  action='/account/applications/?'
  key='API_KEY'
  secret='API_SECRET'
  name='MyFirstApplication'
  type='voice'
  answer_url='https://example.com/ncco'
  event_url='https://example.com/call_status'

  curl $base_url$version$action \
    -d api_key=$key \
    -d api_secret=$secret \
    -d name=$name \
    -d type=$type \
    -d answer_url=$answer_url \
    -d event_url=$event_url
  1. Copy the output private key text and put into private.key

  2. Run this example and get an expected error relating to the fact newline characters haven't been replaced (likely cause):

› node voice/outbound-call.js
crypto.js:282
  var ret = this._handle.sign(toBuf(key), null, passphrase);
                         ^

Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
    at Error (native)
    at Sign.sign (crypto.js:282:26)
    at Object.sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jwa/index.js:54:45)
    at Object.jwsSign [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jws/lib/sign-stream.js:23:24)
    at Object.module.exports [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jsonwebtoken/sign.js:144:16)
    at sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:23:19)
    at Object.<anonymous> (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:28:13)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
  1. Replace \n with real newline characters and run the same example:
› node voice/outbound-call.js
crypto.js:282
  var ret = this._handle.sign(toBuf(key), null, passphrase);
                         ^

Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
    at Error (native)
    at Sign.sign (crypto.js:282:26)
    at Object.sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jwa/index.js:54:45)
    at Object.jwsSign [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jws/lib/sign-stream.js:23:24)
    at Object.module.exports [as sign] (/Users/leggetter/nexmo/git/nexmo-node-quickstart/node_modules/jsonwebtoken/sign.js:144:16)
    at sign (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:23:19)
    at Object.<anonymous> (/Users/leggetter/nexmo/git/nexmo-node-quickstart/voice/outbound-call.js:28:13)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
  1. Fix up the private key which "works for me":
› openssl rsa -in private.key -out private.key
writing RSA key
  1. Run the example and it now works.

@cbetta could we add an outbound calling example to https://github.com/nexmo-community/nexmo-ruby-quickstart (since I think you have the basic code) and then I can try the same process there? I'm wondering if step 4 will be required for Ruby (or other languages) and that the ASN1_CHECK_TLEN:wrong tag is Node specific.

@leggetter
Copy link
Contributor Author

Changing the header and footer in the original downloaded keyfile also fixes the problem:

Current header: BEGIN RSA PRIVATE KEY
Current footer: END RSA PRIVATE KEY

Remove RSA:

Updated header: BEGIN PRIVATE KEY
Updated footer: END PRIVATE KEY

My present suggest is that the Application API should be updated to return the keyfile without the RSA. With RSA is PKCS#1. Without is PKCS#8. I believe we intend to be using PKCS#8.

@cbetta
Copy link
Contributor

cbetta commented Sep 2, 2016

Nice find! Seems indeed that the API should probably be updated.

leggetter referenced this issue in Vonage/vonage-node-sdk Sep 7, 2016
@leggetter
Copy link
Contributor Author

Fixed with an API update. The problem was #81 (comment)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants