aboutsummaryrefslogtreecommitdiff
path: root/gpg/skeybase/src/main/scala/com/github/jodersky/skeybase/openpgp/GnuPG.scala
blob: 3b2d1523c41db7e49b5b6165f3d8f10290c03487 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.github.jodersky.skeybase
package openpgp

import java.io.File
import scala.sys.process._
import java.io.ByteArrayInputStream
import scala.collection.mutable.ArrayBuffer
import verification.VerificationException
import scala.util.Try

class GnuPG(
    val home: File = new File("."),
    val command: String = "/usr/bin/gpg")
  extends Backend {

  import GnuPG._

  private val _gpg = s"${command} --home=${home.getAbsolutePath} --no-default-keyring --keyring=temp.gpg --status-fd=2"
  private def gpg(args: String) = _gpg + " " + args

  def importKey(key: String) = {
    val result = (gpg("--import -") #< stream(key)).!
    result == 0
  }

  def verifySignature(statement: String, fingerprint: String): Try[String] = Try{
    val stdout = new StringBuilder
    val stderr = new ArrayBuffer[String]

    val status = (gpg("-d -") #< stream(statement)) ! ProcessLogger(stdout append _, stderr append _)
    
    if (status != 0) throw new VerificationException("gpg exited with non-zero exit code")

    /* see doc/DETAILS of GnuPG for more information about structure */
    def fpr(line: String) = """\[GNUPG:\] VALIDSIG (\S+\s+){9}(\w+)""".r findPrefixMatchOf (line) map { m =>
      m.group(2)
    }
    
    val valid = stderr find (fpr(_) == Some(fingerprint))
    
    if (valid.isEmpty) {
      throw new VerificationException("Statement is not signed by the correct key.")
    } else {
      stdout.toString()
    }
  }

}

object GnuPG {

  private def stream(str: String) = {
    val bytes = str.getBytes("UTF-8")
    new ByteArrayInputStream(bytes)
  }

  val tmp = "~/.skeybase"
}