okta/okta-sdk-nodejs

PEM routines:get_name:no start line error appearing after following tutorial

abroadhurstDistology opened this issue · 4 comments

Current behavior

I followed this tutorial:

The sdk return the following error:

Error: error:0909006C:PEM routines:get_name:no start line
    at Sign.sign (internal/crypto/sig.js:110:29)
    at Jwt.sign (C:\Users\AliceBroadhurst\source\repos\okta_service_app_example\node_modules\njwt\index.js:229:63)
    at Jwt.compact (C:\Users\AliceBroadhurst\source\repos\okta_service_app_example\node_modules\njwt\index.js:251:29)
    at C:\Users\AliceBroadhurst\source\repos\okta_service_app_example\node_modules\@okta\okta-sdk-nodejs\src\oauth.js:80:24
    at processTicksAndRejections (internal/process/task_queues.js:95:5) {
  library: 'PEM routines',
  function: 'get_name',
  reason: 'no start line',
  code: 'ERR_OSSL_PEM_NO_START_LINE'
}

I am using the public key as the tutorial describes for use while developing.
It seems to be thinking it is reading a PEM file however a JSON object containing a JWT (shown below):

client = new okta.Client({
    orgUrl: 'https://{{org}}.oktapreview.com/',
    authorizationMode: 'PrivateKey',
    clientId: '{{clientid}}',
    scopes: ['okta.users.manage'],
    privateKey: '{"kty": "RSA","e": "AQAB","use": "sig","kid": "cool","alg": "RS256","n": "pMeimZfvtuHYubc9evwvW2aYW_d1UtS6DobJlD2EdQbN6a-fquyPEqS3GXdJdmgAQ6iSZVMrFBeVxW67R7zeA2VY8s7iM_VsnuLnHSKfrnrgtJ6oxOsaajTiKIbYxkPb__aMuzcWWb7I90BHIk5LNCoIAL2P7uBQTZmlUqfX8JCziLlTFXacmST5amtT7Lb3FdYNOOG8-Oz6i91MOo3mdxm-J_gTOSdmCfIgWP2kZu6qHoEoRISEz9JUW-mrYUfyxPAnsKWTJ1Afc999yImssfRjTwTPcfhuQmhB-BoH_dl3-eihoLwgRBY9cQRqIOLvRwI2jmaPSVxdQHNqBHjvgQ"}' // <-- see notes below
});

Expected behavior

To reject/accept the key or return an error stating it is in an invalid format.

Minimal reproduction of the problem with instructions

The app.js code is inserted below (nodejs express 4 project)

'use strict';
var debug = require('debug')('my express app');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
const okta = require('@okta/okta-sdk-nodejs');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

var clientKeys = {};
var client = undefined;

client = new okta.Client({
    orgUrl: 'https://{{org}}.oktapreview.com/',
    authorizationMode: 'PrivateKey',
    clientId: '{{clientid}}',
    scopes: ['okta.users.manage'],
    privateKey: '{"kty": "RSA","e": "AQAB","use": "sig","kid": "cool","alg": "RS256","n": "pMeimZfvtuHYubc9evwvW2aYW_d1UtS6DobJlD2EdQbN6a-fquyPEqS3GXdJdmgAQ6iSZVMrFBeVxW67R7zeA2VY8s7iM_VsnuLnHSKfrnrgtJ6oxOsaajTiKIbYxkPb__aMuzcWWb7I90BHIk5LNCoIAL2P7uBQTZmlUqfX8JCziLlTFXacmST5amtT7Lb3FdYNOOG8-Oz6i91MOo3mdxm-J_gTOSdmCfIgWP2kZu6qHoEoRISEz9JUW-mrYUfyxPAnsKWTJ1Afc999yImssfRjTwTPcfhuQmhB-BoH_dl3-eihoLwgRBY9cQRqIOLvRwI2jmaPSVxdQHNqBHjvgQ"}' // <-- see notes below
});


//https://github.com/okta/okta-sdk-nodejs

app.get('/', function (req, res) {
    try {
        console.log("listUsers")
        const orgUsers = client.listUsers();
        console.log("print users");
        orgUsers.each(user => {
            console.log(user);
        }).then(() => console.log('All users have been listed')).catch((e) => console.log(e));
    } catch (e) {
        console.log("index error");
        console.log("list error:" + e);
    }
    console.log("end");
    res.render('index', { title: 'Express' });
});



// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function (err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

app.set('port', process.env.PORT || 3000);


var server = app.listen(app.get('port'), function () {
    debug('Express server listening on port ' + server.address().port);
});

Environment

  • OS: Windows 10
  • Node.js version: 6.14.15
  • Other:
    -version of sdk: version 5

@abroadhurstDistology Thanks for reporting this issue, we're looking into it

Internal Ref: OKTA-441179

In the meantime, do you mind trying to pass the privateKey as an object rather than a stringified object?

  ....,
      privateKey: {"kty": "RSA","e": "AQAB","use": "sig","kid": "cool","alg": "RS256","n": "abc***************"}
   ...

I get the same error where it seems to think it is a PEM file and has no start line.

I believe the issue is the key you're passing to the okta.Client via privateKey is actually a public key. The public key created in the tutorial is used to create a service app (a public key is a required field). Notice in the tutorial, the public key (jwks) is inside the POST body, rather than the Authorization header and the Authorization header includes an api_token.

Based on the Express app snippet you provided, you may want to try initializing the okta.Client like so:

const okta = require('@okta/okta-sdk-nodejs');

const client = new okta.Client({
  orgUrl: 'https://dev-1234.oktapreview.com/',
  token: 'xYzabc'    // Obtained from Developer Dashboard
});

Let me know how that works for you

i think you may be right thank you