windows Binary Signing

for the last few days ive been playing roung with making my own builds but the thing i cant figger out is

i cant find a way to sign the binarys used this setup

and this is how i have tryed to do the signing

but get errors like this

stsigtool sign syncthing.exe PRIVATE-KEY.PEM panic: runtime error: invalid memory address or nil pointer dereference [signal 0xc0000005 code=0x1 addr=0x0 pc=0x47421c]

goroutine 1 [running]: panic(0x757200, 0xc082008070) C:/Go/src/runtime/panic.go:481 +0x3f4, 0xf11e00, 0xf12000, 0xf, 0x0, 0x0) C:/Go/src/ +0x9c, 0xf11e00, 0xf12000, 0xb84710, 0xc082fd6008, 0x0, 0x0, 0x0, 0x0, 0x0) C:/Go/src/ +0x7d main.sign(0xc082008230, 0xd, 0xc082004640, 0xf) C:/Go/src/ +0x227 main.main() C:/Go/src/ +0x3e5

or this

stsigtool sign PRIVATE-KEY.PEM and all this has under it is a flashing icon and dose nothing else

but still nothing i want to host my builds on my own server as im makeing changes for a network of friends

if anyone could help me out i would be very grateful

Which version of Windows are you using?

windows 10

Granted, that’s hardly the best error message in the world, but:

jb@syno:~/s/g/s/syncthing $ stsigtool 
	stsigtool <command>

Where command is one of:
	sign <privkeyfile> [datafile]
		- sign a file

You should give it the private key followed by the binary to sign, i.e. the opposite of what you’re doing there. The unfortunate error that you see comes from failing to parse the first parameter as a private key file.

You also don’t need to create a signature unless you intend to distribute the binary using the automatic upgrade system. The automatic upgrade system is the only consumer of these signatures; not, for example, Windows itself that has another way of signing binaries.

1 Like

ok then i ran

stsigtool sign PRIVATE-KEY.PEM syncthing.exe




It ran but didnt give a sig file and yes im wanting to run it on my own update server as makeing some changes to make it easyer for some of the people in the network to use/setup

and sorry if im sounding stupid

What you actually need to do, now that I think more about it (we changed this in 0.13) is pipe the archive file name and binary through stsigtool as above, and save it as .metadata/release.sig in the release archive. See this line in the release tools script that does this for the exact procedure:

There is also a syncthing.sig which is the same without the archive file name being part of the signature. This is consumed by v0.12.earlier releases.

Compare what you do with what you can see in one of the official release packages on GitHub.

That script is what does the signing I do on every release. We should update the docs.

And don’t forget that you need to update to include the public portion of the key you created with stsigtool gen.

ok made all the changes you said about

stsigtool verify syncthing.sig syncthing.exe

incorrect signature


stsigtool verify syncthing.sig syncthing.exe PUBLIC-KEY.PEM

correct signature

i even remade the .PEM files and redid signingkey.go as well

Yep, that’s as expected. stsigtool has the official key embedded and will use that unless given another key on the command line.

Once you’ve created a package archive, you can test it by uploading it to wherever and running syncthing -upgrade-to https://url-to-the-package, as syncthing will go through the whole upgrade and verification process there. Note then that

  • The package must be signed with the above highlighted archive name + binary contents method
  • The syncthing you’re upgrading from must be compiled with the public key that you used to sign the package
  • The archive must actually be called what was included in the signature :slight_smile:

ok so i have added the .sig file into the .zip file but i still cant find where to make the .metadata/release.sig file

i feel so close but still so far

ok i have got that all in now :slight_smile: but now getting this

syncthing -upgrade-to 19:51:44 FATAL: Upgrade: asn1: structure error: tags don’t match (2 vs {class:0 tag:16 length:16 isCompound:true}) {optional:false explicit:false application:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false} @2

At a guess, the signature file isn’t a signature file?

ok then how to i run this command under windows?

( echo “$f”; cat “$base/syncthing.exe” ) | stsigtool sign “$PRIVATE_KEY” > “$base/metadata/release.sig”

Sorry, I don’t know. Perhaps you can create a temporary file containing first the filename, a newline (UNIX newline even, not Windows), then the contents of the syncthing.exe, then sign that.

If you’re a programmer of any kind it may even be easiest to automate this with anything from Go via C# to Visual Basic…

I don’t have Windows at hand right now to test this, but somthing like this could work:

( echo %f% & type "%base%/syncthing.exe" ) | stsigtool sign "%PRIVATE_KEY%" > "%base%/metadata"

But that probably will have windows newline, not unix newline :wink:

1 Like

Windows 10 will get “Bash”, right? (with the anniversary update, I think)

So then you will be able to use that and the default script.