Compare commits
2 Commits
master
...
keygen-rem
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78e7c125d2 | ||
|
|
ae1d86a4f3 |
@ -2,6 +2,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [2.4.4] - 2015-04-14
|
||||
### Changed
|
||||
- Separated key utilities into its own Gem
|
||||
|
||||
## [2.4.3] - 2015-04-13
|
||||
### Changed
|
||||
- Loosened production gem requirements from patch level to major level
|
||||
|
||||
## [2.4.2] - 2015-03-11
|
||||
### Fixed
|
||||
- GitHub issue 39: handling post paths that include a ? and require a token. A workaround exists for this issue.
|
||||
|
||||
4
Gemfile
4
Gemfile
@ -1,6 +1,2 @@
|
||||
source 'https://rubygems.org'
|
||||
gemspec
|
||||
|
||||
platform :jruby do
|
||||
gem 'jruby-openssl'
|
||||
end
|
||||
@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
||||
|
||||
s.add_dependency 'json', '~>1.8'
|
||||
s.add_dependency 'rack', '~>1.5'
|
||||
s.add_dependency 'ecdsa', '~>1.2'
|
||||
s.add_dependency 'bitpay-key-utils', '~>2.0.0'
|
||||
|
||||
s.add_development_dependency 'rake', '10.3.2'
|
||||
s.add_development_dependency 'webmock', '1.18.0'
|
||||
|
||||
@ -28,6 +28,7 @@ Then(/^they will receive an array of refunds$/) do
|
||||
end
|
||||
|
||||
Given(/^a properly formatted cancellation request$/) do
|
||||
sleep(1)
|
||||
client = new_client_from_stored_values
|
||||
@refund_id = client.get_all_refunds_for_invoice(id: REFUND_TRANSACTION).first["id"]
|
||||
@response = client.cancel_refund(invoice_id: REFUND_TRANSACTION, request_id: @refund_id)
|
||||
|
||||
@ -6,7 +6,7 @@ require 'uri'
|
||||
require 'net/https'
|
||||
require 'json'
|
||||
|
||||
require_relative 'key_utils'
|
||||
require 'bitpay_key_utils'
|
||||
require_relative 'rest_connector'
|
||||
|
||||
module BitPay
|
||||
|
||||
@ -1,124 +0,0 @@
|
||||
# license Copyright 2011-2014 BitPay, Inc., MIT License
|
||||
# see http://opensource.org/licenses/MIT
|
||||
# or https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
|
||||
require 'uri'
|
||||
require 'net/https'
|
||||
require 'json'
|
||||
require 'openssl'
|
||||
require 'ecdsa'
|
||||
require 'securerandom'
|
||||
require 'digest/sha2'
|
||||
require 'cgi'
|
||||
|
||||
module BitPay
|
||||
class KeyUtils
|
||||
class << self
|
||||
def nonce
|
||||
Time.now.utc.strftime('%Y%m%d%H%M%S%L')
|
||||
end
|
||||
|
||||
## Generates a new private key
|
||||
#
|
||||
|
||||
def generate_pem
|
||||
key = OpenSSL::PKey::EC.new("secp256k1")
|
||||
key.generate_key
|
||||
key.to_pem
|
||||
end
|
||||
|
||||
def create_key pem
|
||||
OpenSSL::PKey::EC.new(pem)
|
||||
end
|
||||
|
||||
def create_new_key
|
||||
key = OpenSSL::PKey::EC.new("secp256k1")
|
||||
key.generate_key
|
||||
key
|
||||
end
|
||||
|
||||
def get_private_key key
|
||||
key.private_key.to_int.to_s(16)
|
||||
end
|
||||
|
||||
def get_public_key key
|
||||
key.public_key.group.point_conversion_form = :compressed
|
||||
key.public_key.to_bn.to_s(16).downcase
|
||||
end
|
||||
|
||||
def get_private_key_from_pem pem
|
||||
raise BitPayError, MISSING_PEM unless pem
|
||||
key = OpenSSL::PKey::EC.new(pem)
|
||||
get_private_key key
|
||||
end
|
||||
|
||||
def get_public_key_from_pem pem
|
||||
raise BitPayError, MISSING_PEM unless pem
|
||||
key = OpenSSL::PKey::EC.new(pem)
|
||||
get_public_key key
|
||||
end
|
||||
|
||||
def generate_sin_from_pem pem
|
||||
#http://blog.bitpay.com/2014/07/01/bitauth-for-decentralized-authentication.html
|
||||
#https://en.bitcoin.it/wiki/Identity_protocol_v1
|
||||
|
||||
# NOTE: All Digests are calculated against the binary representation,
|
||||
# hence the requirement to use [].pack("H*") to convert to binary for each step
|
||||
|
||||
#Generate Private Key
|
||||
key = OpenSSL::PKey::EC.new pem
|
||||
key.public_key.group.point_conversion_form = :compressed
|
||||
public_key = key.public_key.to_bn.to_s(2)
|
||||
step_one = Digest::SHA256.hexdigest(public_key)
|
||||
step_two = Digest::RMD160.hexdigest([step_one].pack("H*"))
|
||||
step_three = "0F02" + step_two
|
||||
step_four_a = Digest::SHA256.hexdigest([step_three].pack("H*"))
|
||||
step_four = Digest::SHA256.hexdigest([step_four_a].pack("H*"))
|
||||
step_five = step_four[0..7]
|
||||
step_six = step_three + step_five
|
||||
encode_base58(step_six)
|
||||
end
|
||||
|
||||
|
||||
## Generate ECDSA signature
|
||||
# This is the last method that requires the ecdsa gem, which we would like to replace
|
||||
|
||||
def sign(message, privkey)
|
||||
group = ECDSA::Group::Secp256k1
|
||||
digest = Digest::SHA256.digest(message)
|
||||
signature = nil
|
||||
while signature.nil?
|
||||
temp_key = 1 + SecureRandom.random_number(group.order - 1)
|
||||
signature = ECDSA.sign(group, privkey.to_i(16), digest, temp_key)
|
||||
return ECDSA::Format::SignatureDerString.encode(signature).unpack("H*").first
|
||||
end
|
||||
end
|
||||
|
||||
########## Private Class Methods ################
|
||||
|
||||
## Base58 Encoding Method
|
||||
#
|
||||
private
|
||||
def encode_base58 (data)
|
||||
code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
base = 58
|
||||
x = data.hex
|
||||
output_string = ""
|
||||
|
||||
while x > 0 do
|
||||
remainder = x % base
|
||||
x = x / base
|
||||
output_string << code_string[remainder]
|
||||
end
|
||||
|
||||
pos = 0
|
||||
while data[pos,2] == "00" do
|
||||
output_string << code_string[0]
|
||||
pos += 2
|
||||
end
|
||||
|
||||
output_string.reverse()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -3,5 +3,5 @@
|
||||
# or https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
|
||||
|
||||
module BitPay
|
||||
VERSION = '2.4.3'
|
||||
VERSION = '2.4.4'
|
||||
end
|
||||
|
||||
@ -22,10 +22,7 @@ module BitPay
|
||||
# User agent reported to API
|
||||
USER_AGENT = 'ruby-bitpay-sdk '+VERSION
|
||||
|
||||
MISSING_PEM = 'No pem file specified. Pass pem string'
|
||||
|
||||
class BitPayError < StandardError; end
|
||||
class ArgumentError < ArgumentError; end
|
||||
class ConnectionError < Errno::ECONNREFUSED; end
|
||||
|
||||
end
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe BitPay::KeyUtils do
|
||||
let(:key_utils) {BitPay::KeyUtils}
|
||||
|
||||
describe '.generate_pem' do
|
||||
it 'should generate a pem string' do
|
||||
regex = /BEGIN\ EC\ PRIVATE\ KEY/
|
||||
expect(regex.match(key_utils.generate_pem)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '.get_public_key_from_pem' do
|
||||
it 'should generate the right public key' do
|
||||
expect(key_utils.get_public_key_from_pem(PEM)).to eq(PUB_KEY)
|
||||
end
|
||||
|
||||
it 'should get pem from the env if none is passed' do
|
||||
expect(key_utils.get_public_key_from_pem(PEM)).to eq(PUB_KEY)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '.generate_sin_from_pem' do
|
||||
let(:pem){PEM}
|
||||
let(:sin){CLIENT_ID}
|
||||
|
||||
it 'will return the right sin for the right pem' do
|
||||
expect(key_utils.generate_sin_from_pem(pem)).to eq sin
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "errors when priv_key is not provided" do
|
||||
it 'will not retrieve public key' do
|
||||
expect{key_utils.get_public_key_from_pem(nil)}.to raise_error(BitPay::BitPayError)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user