diff --git a/server/go/sigserver/verify.go b/server/go/sigserver/verify.go index 453d6d462..da982a2a6 100644 --- a/server/go/sigserver/verify.go +++ b/server/go/sigserver/verify.go @@ -15,14 +15,16 @@ package main import ( "bytes" -// "crypto/openpgp/armor" -// "crypto/openpgp/packet" + "crypto/openpgp/armor" + "crypto/openpgp/packet" /// "crypto/rsa" // "crypto/sha1" -// "io/ioutil" "camli/blobref" + "fmt" + "io/ioutil" "json" "log" + "os" "flag" "camli/http_util" "http" @@ -33,6 +35,27 @@ const sigSeparator = `,"camliSig":"` var flagPubKeyDir *string = flag.String("pubkey-dir", "test/pubkey-blobs", "Temporary development hack; directory to dig-xxxx.camli public keys.") +func readOpenPGPPacketFromArmoredFileOrDie(fileName string, armorType string) (p packet.Packet) { + data, err := ioutil.ReadFile(fileName) + if err != nil { + log.Exit("Cannot open '%s': %s", fileName, err) + } + + block, _ := armor.Decode(data) + if block == nil { + log.Exit("cannot parse armor") + } + if block.Type != armorType { + log.Exitf("bad type in '%s' (got: %s, want: %s)", fileName, block.Type, armorType) + } + buf := bytes.NewBuffer(block.Bytes) + p, err = packet.ReadPacket(buf) + if err != nil { + log.Exitf("failed to parse packet from '%s': %s", fileName, err) + } + return +} + func handleVerify(conn http.ResponseWriter, req *http.Request) { if !(req.Method == "POST" && req.URL.Path == "/camli/sig/verify") { http_util.BadRequestError(conn, "Inconfigured handler.") @@ -85,6 +108,7 @@ func handleVerify(conn http.ResponseWriter, req *http.Request) { verifyFail("parse error; JSON is invalid") return } + log.Printf("Got json: %v", sjsonKeys) if _, hasVersion := sjsonKeys["camliVersion"]; !hasVersion { verifyFail("Missing 'camliVersion' in the JSON payload") @@ -109,12 +133,48 @@ func handleVerify(conn http.ResponseWriter, req *http.Request) { } log.Printf("Signer: %v", signerBlob) - sigKey := make(map[string]interface{}) - if err := json.Unmarshal(BPJ, &sigKey); err != nil { - verifyFail("parse error; signature JSON invalid") + sigKeyMap := make(map[string]interface{}) + if err := json.Unmarshal(BS, &sigKeyMap); err != nil { + verifyFail("parse error; signature JSON invalid") + return } - - log.Printf("Got json: %v", sjsonKeys) + log.Printf("Got sigKeyMap: %v", sigKeyMap) + if len(sigKeyMap) != 1 { + verifyFail("signature JSON didn't have exactly 1 key") + return + } + sigVal, hasCamliSig := sigKeyMap["camliSig"] + if !hasCamliSig { + verifyFail("no 'camliSig' key in signature") + return + } + + log.Printf("sigValu = [%s]", sigVal) + + // verify that we have the public key signature file + publicKeyFile := fmt.Sprintf("%s/%s.camli", *flagPubKeyDir, signerBlob.String()) + pubf, err := os.Open(publicKeyFile, os.O_RDONLY, 0) + if err != nil { + verifyFail(fmt.Sprintf("couldn't find the public key for camliSigner %s: %v", + signerBlob, err)) + } + defer pubf.Close() + + log.Printf("Opened public key file") + + pubKeySlurp, err := ioutil.ReadAll(pubf) + if err != nil { + verifyFail(fmt.Sprintf("Error reading public key file: %v", err)) + return + } + + block, _ := armor.Decode(pubKeySlurp) + if block == nil { + verifyFail("Couldn't find PGP block in public key file") + return + } + + log.Printf("TODO: finish implementing") conn.WriteHeader(http.StatusNotImplemented) conn.Write([]byte("TODO: implement")) }