Skip to content
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

Invalid Signature #213

Open
ArkajyotiChatterjee opened this issue Mar 12, 2018 · 10 comments
Open

Invalid Signature #213

ArkajyotiChatterjee opened this issue Mar 12, 2018 · 10 comments
Labels
topic: documentation Related to documentation for the project type: enhancement Proposed improvement

Comments

@ArkajyotiChatterjee
Copy link

ArkajyotiChatterjee commented Mar 12, 2018

Hello. I am trying to call the arduino create agent plugin from my localhost to upload a hex file to my arduino. I generated a pair of public and private keys and updated the public key in the config.ini file. Then I am generating the signature of my commandline using my private key and then I am updating the same on the js code. But still when I run the code, I am getting "Signature is Invalid". Any ideas as to what I am doing wrong. I am pasting the json payload I am trying to upload .

var abcData = {
           "board":"arduino:avr:uno",
           "port":"COM18",
           "commandline":"\"C:\Program Files(x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM15 -b115200 -D -Uflash:w:C:\Users\ChatteAr\AppData\Local\Temp\arduino_build_876546/flasher_tryout.ino.hex:i\"",
           "signature":"uJsl8iXd9hNsA6ExtE7msUGaP1/9KU+Yx...." ,
          "hex":"EAAAAAyUXQAMlIUADJSFAAyUhQCEEAAQAAyUhQAMlIUADJSFAAyUhQBMEAAgAAyUhQAMlIUAD.....",
           "filename":"flasher_tryout.ino.hex",
		   "extra":{
              "auth":{
			     "username":null,
                 "password":null,
				  "privatekey":null,
				   "port":null
                },
              "wait_for_upload_port":false,
              "use_1200bps_touch":false,
              "network":false,
              "params_verbose":null,
              "params_quiet":null,
              "verbose":false ,
			  "ssh":false}
        
    };
url= "http://localhost:8991/upload";
@facchinm
Copy link
Member

Hi @ArkajyotiChatterjee ,
the procedure looks good. @matteosuppo we don't need to sign anything except the commandline right now, correct?

@matteosuppo
Copy link
Contributor

Yes, only the commandline. The key should be crypto.SHA256.

@ArkajyotiChatterjee
Copy link
Author

ArkajyotiChatterjee commented Mar 12, 2018

Hi @facchinm , @matteosuppo , for testing purposes I was using openSSL from my GIT Bash to generate the key pair and sign the commandline. The codes are as follows:
`openssl genrsa -out private.pem 2048 // private key

openssl rsa -in private.pem -outform PEM -pubout -out public.pem //public key(used in config.ini)

echo ""{runtime.tools.avrdude.path}/bin/avrdude" "-C{runtime.tools.avrdude.path}/etc/avrdude.conf" {upload.verbose} -patmega32u4 -cavr109 -P{serial.port} -b57600 -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"" | openssl dgst -sha256 -sign private.pem -out /tmp/sign.sha256
//signing the commandline

openssl base64 -in /tmp/sign.sha256 -out sign_commndline // the signature file`

Still I am getting the error"Signature is Invalid". Any ideas as to exactly what I am missing?

@ArkajyotiChatterjee
Copy link
Author

Hey guys,any help would be appreciated a lot.

@matteosuppo
Copy link
Contributor

The only thing that comes to mind it that maybe the quotes are being escaped.

You could try with the following go code:

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
)
func sign(message []byte, key []byte) ([]byte, error) {
	block, _ := pem.Decode(key)
	if block == nil {
		return nil, errors.New("While decoding key " + string(key))
	}
	rng := rand.Reader
	private, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, errors.New("While parsing key "+ key)
	}

	hashed := sha256.Sum256(message)
	signature, err := rsa.SignPKCS1v15(rng, private, crypto.SHA256, hashed[:])
	if err != nil {
		return nil, errors.New("While signing message "+message+" with key " + private)
	}

	return signature, nil
}

and see if the generated signature is the same

@kosciuk
Copy link

kosciuk commented Feb 17, 2019

I don't know the entire process but if I run --generateCert all keys are ECDSA,I think the signature must be made with key.pem, but the function verifyCommandLine seems to use a RSA in line 216:
key.(*rsa.PublicKey)

Log

http2: panic serving 127.0.0.1:43880: interface conversion: interface {} is *ecdsa.PublicKey, not *rsa.PublicKey
goroutine 156 [running]:
net/http.(*http2serverConn).runHandler.func1(0xc420206038, 0xc4205dbfaf, 0xc420348000)
/usr/lib/go-1.10/src/net/http/h2_bundle.go:5753 +0x190
panic(0xb52080, 0xc4202008c0)
/usr/lib/go-1.10/src/runtime/panic.go:502 +0x229
main.verifyCommandLine(0xc42012e540, 0xd4, 0xc4200923f0, 0x61, 0x6, 0x414038)
/home/kosciuk/go/src/github.com/arduino/arduino-create-agent/conn.go:215 +0x2c4

@matteosuppo
Copy link
Contributor

The certificates generated with --generateCert are only used for ssl, they are not used to sign the commandline

@kosciuk
Copy link

kosciuk commented Feb 19, 2019

Ups! I used key.pem to sign. I ' ll try generating my own RSA, but with ECDSA I can't verify the signature until I generated it with Python [0], maybe there is a problem with signing with openssl.

[0] https://thanethomson.com/2018/11/30/validating-ecdsa-signatures-golang/

@matteosuppo
Copy link
Contributor

It shouldn't be possible to verify a signature with a ecdsa key, since it expects an rsa public key

@kosciuk
Copy link

kosciuk commented Feb 26, 2019

Not if I add a new function for that :P, I tried again with RSA and the problem was that

openssl base64 -in /tmp/sign.sha256 -out sign_commndline

is wrong since the code expect the signature in hex:

func verifyCommandLine(input string, signature string) error {
    sign, _ := hex.DecodeString(signature)

I couldn't create the signature with openssl or Python, then I used the example in https://stackoverflow.com/questions/20655702/signing-and-decoding-with-rsa-sha-in-go. The digest was the same in Python - Go, but the signature didn't match (using pip install rsa)

Update:

Finally... how to make the signature:

#!/usr/bin/env python

from base64 import (
    b64encode,
    b64decode,
)

from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA

digest = SHA256.new()
digest.update(b'"{runtime ... [complete with your command line] ... }.hex:i"')

with open ("rsakey.pem", "r") as myfile:
    private_key = RSA.importKey(myfile.read())

signer = PKCS1_v1_5.new(private_key)
sig = signer.sign(digest)

print(sig.encode("hex"))

Hope this helps, @ArkajyotiChatterjee

@umbynos umbynos added topic: documentation Related to documentation for the project type: enhancement Proposed improvement labels Feb 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: documentation Related to documentation for the project type: enhancement Proposed improvement
Projects
None yet
Development

No branches or pull requests

5 participants