TL/DR: ssh-keygen only signs public keys. However, it tries to recover from being passed a private key by looking for an appropriately named public key automatically and gives no warning messages.
Unfortunately, SSH keys do not implement trusted third party as certificates do. SSH keys are quite basic, they are just "keys" as the name imply, without all the bell and whistles you may find in certificates (certificates being actually a key wrapped in a container adding supplementary information, and the CA signature is part of this container).
Would you need to find a way to handle SSH keys on a large number of hosts, you may be interested in this thread, where a solution is proposed to use MonkeySphere which relies on OpenPGP web of trust to add trusted third party concepts including to OpenSSH.
Edit: As appeared in the discussion below, openSSH added a specific feature implementing signing a public key using a third party CA key.
The command given in the question, "ssh-keygen -s ca.key -I dev1 dev1.key" does not work because, as stated in ssh-keygen manpage, dev1.key must be a public key.
However, when the file given as parameter is not a valid public key, before giving up ssh-keygen will check for the existence of a file named {filename}.pub which may contain the expected public key.
In the case of keys generated using ssh-keygen, this *.pub file is automatically generated, so when giving the private key file as parameter ssh-keygen will transparently fallback on the public key file.
However, key files manually generated from SSL certificates did not respect the same convention (the file dev1.key did not have its dev1.key.pub counterpart), and that's what it was failing in this case.
Edit 2: Checking this behavior is as simple as launching the command below
strace ssh-keygen -s ca.key -I dev1 dev1
The behavior I describe appear here:
# First ssh-keygen try to open the file given as parameter:
...
open("dev1", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0600, st_size=1671, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f15ec1c0000
# Then it reads its content:
read(3, "-----BEGIN RSA PRIVATE KEY-----\n"..., 4096) = 1671
# Seeing it is not a public key, it closes it:
close(3) = 0
munmap(0x7f15ec1c0000, 4096) = 0
# Then he checks if a file with extension .pub exists:
open("dev1.pub", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=405, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f15ec1c0000
# If it exists, it reads it content too to check if it is a valid public key file:
read(3, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB"..., 4096) = 405
# Yes it is, so now having read its content, it closes it and proceeds with
# creating the signed version of this public key (file 'dev1-cert.pub'):
close(3) = 0
munmap(0x7f15ec1c0000, 4096) = 0
open("dev1-cert.pub", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
...