Skip to content

Commit

Permalink
fix(option): removed options from parsing since not required
Browse files Browse the repository at this point in the history
  • Loading branch information
utsavmaniyar committed Jan 29, 2025
1 parent 7ce4e75 commit 013b439
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 95 deletions.
2 changes: 1 addition & 1 deletion pkg/core/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var (
ptrGitStreamInput = flag.Bool("git-commit-stream", false, "Use stream IO of Git commit log as input instead of file(s) -- e.g., 'cat secrets.text > go-earlybird'")
ptrVerbose = flag.Bool("verbose", false, "Reports details about file reads")
ptrSuppressSecret = flag.Bool("suppress", false, "Suppress reporting of the secret found (important if output is going to Slack or other logs)")
ptrStrictJKS = flag.Bool("strict-jks", false, "Checks for private keys in the JKS file and return hits only if found")
ptrStrictJKS = flag.Bool("strict-jks", false, "Checks for private keys in the JKS file and return hits only if found")
ptrWorkerCount = flag.Int("workers", 100, "Set number of workers.")
ptrWorkLength = flag.Int("worksize", 2500, "Set Line Wrap Length.")
ptrMaxFileSize = flag.Int64("max-file-size", 10240000, "Maximum file size to scan (in bytes)")
Expand Down
43 changes: 0 additions & 43 deletions pkg/jks/jks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Package jks provides routines for manipulating Java Keystore files.
package jks

import (
"crypto/sha1"
"crypto/x509"
"time"
"unicode/utf16"
Expand Down Expand Up @@ -38,27 +37,6 @@ type Keystore struct {
Keypairs []*Keypair
}

// Options for manipulating a keystore. These allow the caller to specify the
// password(s) used, or to skip the digest verification if the password is
// unknown.
type Options struct {
// Password is used as part of a SHA-1 digest over the .jks file.
Password string

// SkipVerifyDigest can be set to skip digest verification when loading
// a keystore file. This will inhibit errors from Parse if you don't
// know the password.
SkipVerifyDigest bool

// KeyPasswords are used to generate the "encryption" keys for stored
// private keys. The map's key is the alias of the private key, and the
// value is the password. If there is no entry in the map for a given
// alias, then the top-level Password is inherited. Empty strings are
// interpreted as an empty password, so use delete() if you truly want
// to delete values.
KeyPasswords map[string]string
}

// Cert holds a certificate to trust.
type Cert struct {
// Alias is a name used to refer to this certificate.
Expand Down Expand Up @@ -120,27 +98,6 @@ type KeypairCert struct {
CertErr error
}

var defaultOptions = Options{
SkipVerifyDigest: true,
}

// ComputeDigest performs the custom hash function over the given file data.
// DO NOT RE-USE THIS CODE: this is an atrocious way to perform message
// authentication. Use the HMAC example from
// https://github.com/lwithers/go-crypto-examples instead. Note this construct
// is vulnerable to a length extension attack, which is actually exploitable if
// the JKS reader code does not properly check the "number of entries" value.
func ComputeDigest(raw []byte, passwd string) []byte {
// compute SHA-1 digest over the construct:
// UTF-16(password) + UTF-8(DigestSeparator) + raw
md := sha1.New()
p := PasswordUTF16(passwd)
md.Write(p)
md.Write([]byte(DigestSeparator))
md.Write(raw)
return md.Sum(nil)
}

// PasswordUTF16 returns a password encoded in UTF-16, big-endian byte order.
func PasswordUTF16(passwd string) []byte {
var u []byte
Expand Down
24 changes: 0 additions & 24 deletions pkg/jks/jks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,10 @@ package jks
import (
"bytes"
"encoding/binary"
"encoding/hex"
"testing"
"unicode/utf16"
)

// TestComputeDigest is a regression test for the digest function.
func TestComputeDigest(t *testing.T) {
t.Run("empty", testComputeDigest("", "",
"569D05A766C473698C0B58EBAEAE0A25EB10BACC"))
t.Run("regr", testComputeDigest("input data", "password",
"74DDD13B68919674D4409A19AB284019A1DA57C8"))
}

func testComputeDigest(in, passwd, expHex string) func(*testing.T) {
return func(t *testing.T) {
exp, err := hex.DecodeString(expHex)
if err != nil {
t.Fatalf("error decoding expHex: %v", err)
}
out := ComputeDigest([]byte(in), passwd)
if !bytes.Equal(out, exp) {
t.Errorf("output sequence (len %d) ≠ expected",
len(out))
t.Errorf("out %X", out)
}
}
}

// TestPasswordUTF16 checks that our UTF-16 encoding routine works as expected.
// The test cases incorporate empty strings and Unicode strings with characters
// outside the BMP (basic multilingual plane), i.e. ones that need encoding as
Expand Down
26 changes: 5 additions & 21 deletions pkg/jks/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package jks

import (
"bytes"
"crypto/hmac"
"crypto/x509"
"encoding/binary"
"errors"
Expand All @@ -14,7 +13,7 @@ import (
"time"
)

// Parse a JKS file. If desired, opts may be specified to provide more control
// Parse a JKS file.
// over the parsing. If nil, then we will use an empty password when attempting
// to decrypt keys and will not attempt to verify the digest stored in the file.
//
Expand All @@ -25,10 +24,7 @@ import (
// Parse function returning an error. If digest verification is requested and
// the password or the digest is incorrect, an error will also be returned. If
// any useful data has been extracted it will be returned as a partial Keystore.
func Parse(raw []byte, opts *Options) (*Keystore, error) {
if opts == nil {
opts = &defaultOptions
}
func Parse(raw []byte) (*Keystore, error) {

buf := bytes.NewReader(raw)
ks := new(Keystore)
Expand Down Expand Up @@ -71,7 +67,7 @@ func Parse(raw []byte, opts *Options) (*Keystore, error) {
switch etype {
case 1:
// it's a private key + cert chain
kp, err := readKeypair(buf, opts)
kp, err := readKeypair(buf)
if err != nil {
return ks, err
}
Expand All @@ -96,14 +92,7 @@ func Parse(raw []byte, opts *Options) (*Keystore, error) {
case buf.Len() != 20:
return ks, errors.New("malformed digest at end of file")

case opts.SkipVerifyDigest:
return ks, nil

default:
digest := ComputeDigest(raw[:len(raw)-20], opts.Password)
if !hmac.Equal(digest, raw[len(raw)-20:]) {
return ks, errors.New("digest mismatch")
}
return ks, nil
}
}
Expand Down Expand Up @@ -207,7 +196,7 @@ func readCert(buf *bytes.Reader) (*Cert, error) {
return cert, nil
}

func readKeypair(buf *bytes.Reader, opts *Options) (*Keypair, error) {
func readKeypair(buf *bytes.Reader) (*Keypair, error) {
var (
offset int64
err error
Expand All @@ -220,11 +209,6 @@ func readKeypair(buf *bytes.Reader, opts *Options) (*Keypair, error) {
if err != nil {
return nil, err
}
passwd, ok := opts.KeyPasswords[kp.Alias]
if !ok {
// no specific password for this alias, so use the file password
passwd = opts.Password
}

kp.Timestamp, _, err = readTimestamp(buf)
if err != nil {
Expand All @@ -244,7 +228,7 @@ func readKeypair(buf *bytes.Reader, opts *Options) (*Keypair, error) {

kp.EncryptedKey = make([]byte, elen)
_, _ = buf.Read(kp.EncryptedKey)
kp.RawKey, kp.PrivKeyErr = DecryptPKCS8(kp.EncryptedKey, passwd)
kp.RawKey, kp.PrivKeyErr = DecryptPKCS8(kp.EncryptedKey, "")
if kp.PrivKeyErr == nil {
// we should now have a PKCS#8 PrivateKeyInfo, which Go can
// parse for us
Expand Down
7 changes: 1 addition & 6 deletions pkg/postprocess/jks.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,13 @@ import (
// JKS checks if a file meets standard
func JKS(file string) bool {

opts := &jks.Options{
SkipVerifyDigest: true,
KeyPasswords: nil,
}

raw, err := os.ReadFile(file)
if err != nil {
fmt.Printf("JKS file read Error")
return false
}

ks, err := jks.Parse(raw, opts)
ks, err := jks.Parse(raw)
if err != nil {
println("JKS Parse Error", err)
}
Expand Down

0 comments on commit 013b439

Please sign in to comment.