You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					79 lines
				
				2.1 KiB
			
		
		
			
		
	
	
					79 lines
				
				2.1 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								/*global module*/
							 | 
						||
| 
								 | 
							
								var Buffer = require('safe-buffer').Buffer;
							 | 
						||
| 
								 | 
							
								var DataStream = require('./data-stream');
							 | 
						||
| 
								 | 
							
								var jwa = require('jwa');
							 | 
						||
| 
								 | 
							
								var Stream = require('stream');
							 | 
						||
| 
								 | 
							
								var toString = require('./tostring');
							 | 
						||
| 
								 | 
							
								var util = require('util');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function base64url(string, encoding) {
							 | 
						||
| 
								 | 
							
								  return Buffer
							 | 
						||
| 
								 | 
							
								    .from(string, encoding)
							 | 
						||
| 
								 | 
							
								    .toString('base64')
							 | 
						||
| 
								 | 
							
								    .replace(/=/g, '')
							 | 
						||
| 
								 | 
							
								    .replace(/\+/g, '-')
							 | 
						||
| 
								 | 
							
								    .replace(/\//g, '_');
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function jwsSecuredInput(header, payload, encoding) {
							 | 
						||
| 
								 | 
							
								  encoding = encoding || 'utf8';
							 | 
						||
| 
								 | 
							
								  var encodedHeader = base64url(toString(header), 'binary');
							 | 
						||
| 
								 | 
							
								  var encodedPayload = base64url(toString(payload), encoding);
							 | 
						||
| 
								 | 
							
								  return util.format('%s.%s', encodedHeader, encodedPayload);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function jwsSign(opts) {
							 | 
						||
| 
								 | 
							
								  var header = opts.header;
							 | 
						||
| 
								 | 
							
								  var payload = opts.payload;
							 | 
						||
| 
								 | 
							
								  var secretOrKey = opts.secret || opts.privateKey;
							 | 
						||
| 
								 | 
							
								  var encoding = opts.encoding;
							 | 
						||
| 
								 | 
							
								  var algo = jwa(header.alg);
							 | 
						||
| 
								 | 
							
								  var securedInput = jwsSecuredInput(header, payload, encoding);
							 | 
						||
| 
								 | 
							
								  var signature = algo.sign(securedInput, secretOrKey);
							 | 
						||
| 
								 | 
							
								  return util.format('%s.%s', securedInput, signature);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function SignStream(opts) {
							 | 
						||
| 
								 | 
							
								  var secret = opts.secret||opts.privateKey||opts.key;
							 | 
						||
| 
								 | 
							
								  var secretStream = new DataStream(secret);
							 | 
						||
| 
								 | 
							
								  this.readable = true;
							 | 
						||
| 
								 | 
							
								  this.header = opts.header;
							 | 
						||
| 
								 | 
							
								  this.encoding = opts.encoding;
							 | 
						||
| 
								 | 
							
								  this.secret = this.privateKey = this.key = secretStream;
							 | 
						||
| 
								 | 
							
								  this.payload = new DataStream(opts.payload);
							 | 
						||
| 
								 | 
							
								  this.secret.once('close', function () {
							 | 
						||
| 
								 | 
							
								    if (!this.payload.writable && this.readable)
							 | 
						||
| 
								 | 
							
								      this.sign();
							 | 
						||
| 
								 | 
							
								  }.bind(this));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  this.payload.once('close', function () {
							 | 
						||
| 
								 | 
							
								    if (!this.secret.writable && this.readable)
							 | 
						||
| 
								 | 
							
								      this.sign();
							 | 
						||
| 
								 | 
							
								  }.bind(this));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								util.inherits(SignStream, Stream);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SignStream.prototype.sign = function sign() {
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    var signature = jwsSign({
							 | 
						||
| 
								 | 
							
								      header: this.header,
							 | 
						||
| 
								 | 
							
								      payload: this.payload.buffer,
							 | 
						||
| 
								 | 
							
								      secret: this.secret.buffer,
							 | 
						||
| 
								 | 
							
								      encoding: this.encoding
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    this.emit('done', signature);
							 | 
						||
| 
								 | 
							
								    this.emit('data', signature);
							 | 
						||
| 
								 | 
							
								    this.emit('end');
							 | 
						||
| 
								 | 
							
								    this.readable = false;
							 | 
						||
| 
								 | 
							
								    return signature;
							 | 
						||
| 
								 | 
							
								  } catch (e) {
							 | 
						||
| 
								 | 
							
								    this.readable = false;
							 | 
						||
| 
								 | 
							
								    this.emit('error', e);
							 | 
						||
| 
								 | 
							
								    this.emit('close');
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								SignStream.sign = jwsSign;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = SignStream;
							 |