mirror of https://github.com/perkeep/perkeep.git
Merge branch 'master' of danga.com:camlistore
This commit is contained in:
commit
66b7eaf912
|
@ -3,6 +3,7 @@ include $(GOROOT)/src/Make.inc
|
|||
TARG=camsigd
|
||||
GOFILES=\
|
||||
camsigd.go\
|
||||
keys.go\
|
||||
sign.go\
|
||||
verify.go\
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"flag"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"crypto/openpgp/armor"
|
||||
"crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
var flagPubKeyDir *string = flag.String("pubkey-dir", "test/pubkey-blobs",
|
||||
"Temporary development hack; directory to dig-xxxx.camli public keys.")
|
||||
|
||||
func openArmoredPublicKeyFile(fileName string) (*packet.PublicKeyPacket, os.Error) {
|
||||
data, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return nil, os.NewError(fmt.Sprintf("Error reading public key file: %v", err))
|
||||
}
|
||||
|
||||
block, _ := armor.Decode(data)
|
||||
if block == nil {
|
||||
return nil, os.NewError("Couldn't find PGP block in public key file")
|
||||
}
|
||||
if block.Type != "PGP PUBLIC KEY BLOCK" {
|
||||
return nil, os.NewError("Invalid public key blob.")
|
||||
}
|
||||
buf := bytes.NewBuffer(block.Bytes)
|
||||
p, err := packet.ReadPacket(buf)
|
||||
if err != nil {
|
||||
return nil, os.NewError(fmt.Sprintf("Invalid public key blob: %v", err))
|
||||
}
|
||||
|
||||
pk, ok := p.(packet.PublicKeyPacket)
|
||||
if !ok {
|
||||
return nil, os.NewError(fmt.Sprintf("Invalid public key blob; not a public key packet"))
|
||||
}
|
||||
return &pk, nil
|
||||
}
|
||||
|
|
@ -1,17 +1,21 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"camli/blobref"
|
||||
"camli/httputil"
|
||||
"exec"
|
||||
"fmt"
|
||||
"http"
|
||||
"io/ioutil"
|
||||
"json"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const kMaxJsonLength = 1024 * 1024
|
||||
|
||||
func handleSign(conn http.ResponseWriter, req *http.Request) {
|
||||
if !(req.Method == "POST" && req.URL.Path == "/camli/sig/sign") {
|
||||
httputil.BadRequestError(conn, "Inconfigured handler.")
|
||||
|
@ -20,20 +24,46 @@ func handleSign(conn http.ResponseWriter, req *http.Request) {
|
|||
|
||||
req.ParseForm()
|
||||
|
||||
json := req.FormValue("json")
|
||||
if json == "" {
|
||||
httputil.BadRequestError(conn, "Missing json parameter.")
|
||||
jsonStr := req.FormValue("json")
|
||||
if jsonStr == "" {
|
||||
httputil.BadRequestError(conn, "Missing json parameter")
|
||||
return
|
||||
}
|
||||
if len(jsonStr) > kMaxJsonLength {
|
||||
httputil.BadRequestError(conn, "json parameter too large")
|
||||
return
|
||||
}
|
||||
|
||||
var keyId int
|
||||
numScanned, err := fmt.Sscanf(req.FormValue("keyid"), "%x", &keyId)
|
||||
if numScanned != 1 {
|
||||
httputil.BadRequestError(conn, "Couldn't parse keyid parameter.")
|
||||
return
|
||||
trimmedJson := strings.TrimRightFunc(jsonStr, unicode.IsSpace)
|
||||
|
||||
jmap := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(trimmedJson), &jmap); err != nil {
|
||||
httputil.BadRequestError(conn, "json parameter doesn't parse as JSON.")
|
||||
return
|
||||
}
|
||||
|
||||
trimmedJson := strings.TrimRightFunc(json, unicode.IsSpace)
|
||||
camliSigner, hasSigner := jmap["camliSigner"]
|
||||
if !hasSigner {
|
||||
httputil.BadRequestError(conn, "json lacks \"camliSigner\" key with public key blobref")
|
||||
return
|
||||
}
|
||||
|
||||
signerBlob := blobref.Parse(camliSigner.(string))
|
||||
if signerBlob == nil {
|
||||
httputil.BadRequestError(conn, "json \"camliSigner\" key is malformed or unsupported")
|
||||
return
|
||||
}
|
||||
|
||||
publicKeyFile := fmt.Sprintf("%s/%s.camli", *flagPubKeyDir, signerBlob.String())
|
||||
pk, err := openArmoredPublicKeyFile(publicKeyFile)
|
||||
if err != nil {
|
||||
conn.WriteHeader(http.StatusUnauthorized)
|
||||
fmt.Fprintf(conn, "Failed to find public key for %s", signerBlob)
|
||||
return
|
||||
}
|
||||
|
||||
// This check should be redundant if the above JSON parse succeeded, but
|
||||
// for explicitness...
|
||||
if len(trimmedJson) == 0 || trimmedJson[len(trimmedJson)-1] != '}' {
|
||||
httputil.BadRequestError(conn, "json parameter lacks trailing '}'.")
|
||||
return
|
||||
|
@ -46,7 +76,7 @@ func handleSign(conn http.ResponseWriter, req *http.Request) {
|
|||
"--no-default-keyring",
|
||||
"--keyring", *flagRing,
|
||||
"--secret-keyring", *flagSecretRing,
|
||||
"--local-user", fmt.Sprintf("%x", keyId),
|
||||
"--local-user", pk.KeyIdString(),
|
||||
"--detach-sign",
|
||||
"--armor",
|
||||
"-"},
|
||||
|
|
|
@ -21,13 +21,10 @@ my $json = $j->objToJson({ "camliVersion" => 1,
|
|||
"foo" => "bar",
|
||||
});
|
||||
|
||||
print "JSON: [$json]\n";
|
||||
my $keyid = "26F5ABDA"; # test key
|
||||
|
||||
# Sign it.
|
||||
my $sjson;
|
||||
{
|
||||
my $req = req("sign", { "json" => $json, "keyid" => $keyid });
|
||||
my $req = req("sign", { "json" => $json });
|
||||
my $res = $ua->request($req);
|
||||
ok($res, "got an HTTP sig response") or done_testing();
|
||||
ok($res->is_success, "HTTP sig response is successful") or done_testing();
|
||||
|
|
|
@ -21,10 +21,8 @@ import (
|
|||
"crypto/openpgp/packet"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"flag"
|
||||
"fmt"
|
||||
"http"
|
||||
"io/ioutil"
|
||||
"json"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -35,9 +33,6 @@ var logf = log.Printf
|
|||
|
||||
const sigSeparator = `,"camliSig":"`
|
||||
|
||||
var flagPubKeyDir *string = flag.String("pubkey-dir", "test/pubkey-blobs",
|
||||
"Temporary development hack; directory to dig-xxxx.camli public keys.")
|
||||
|
||||
// reArmor takes a camliSig (single line armor) and turns it back into an PGP-style
|
||||
// multi-line armored string
|
||||
func reArmor(line string) string {
|
||||
|
@ -54,32 +49,6 @@ func reArmor(line string) string {
|
|||
`, line[0:lastEq], line[lastEq:])
|
||||
}
|
||||
|
||||
func openArmoredPublicKeyFile(fileName string) (*packet.PublicKeyPacket, os.Error) {
|
||||
data, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return nil, os.NewError(fmt.Sprintf("Error reading public key file: %v", err))
|
||||
}
|
||||
|
||||
block, _ := armor.Decode(data)
|
||||
if block == nil {
|
||||
return nil, os.NewError("Couldn't find PGP block in public key file")
|
||||
}
|
||||
if block.Type != "PGP PUBLIC KEY BLOCK" {
|
||||
return nil, os.NewError("Invalid public key blob.")
|
||||
}
|
||||
buf := bytes.NewBuffer(block.Bytes)
|
||||
p, err := packet.ReadPacket(buf)
|
||||
if err != nil {
|
||||
return nil, os.NewError(fmt.Sprintf("Invalid public key blob: %v", err))
|
||||
}
|
||||
|
||||
pk, ok := p.(packet.PublicKeyPacket)
|
||||
if !ok {
|
||||
return nil, os.NewError(fmt.Sprintf("Invalid public key blob; not a public key packet"))
|
||||
}
|
||||
return &pk, nil
|
||||
}
|
||||
|
||||
// See doc/json-signing/* for background and details
|
||||
// on these variable names.
|
||||
type VerifyRequest struct {
|
||||
|
|
Loading…
Reference in New Issue