Open ArkajyotiChatterjee opened 6 years ago
Hi @ArkajyotiChatterjee , the procedure looks good. @matteosuppo we don't need to sign anything except the commandline right now, correct?
Yes, only the commandline. The key should be crypto.SHA256.
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?
Hey guys,any help would be appreciated a lot.
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
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
The certificates generated with --generateCert are only used for ssl, they are not used to sign the commandline
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/
It shouldn't be possible to verify a signature with a ecdsa key, since it expects an rsa public key
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
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 .