all the directives are copied in with their types. working on validators now.

This commit is contained in:
2020-09-27 03:23:58 -04:00
parent c22786204a
commit 4b912a8dae
21 changed files with 859 additions and 131 deletions

View File

@@ -27,7 +27,8 @@ import (
// Misc
const (
// Where to find an up-to-date copy of the upstream moduli and its SHA3-512 (NIST) checksum.
pregenURL string = "https://anongit.mindrot.org/openssh.git/tree/moduli"
// pregenURL string = "https://anongit.mindrot.org/openssh.git/plain/moduli"
pregenURL string = "https://raw.githubusercontent.com/openssh/openssh-portable/master/moduli"
// This is the best way I could think of to verify integrity, since the file itself doesn't have a signature or anything like that.
pregenCksum string = "106EDB19A936608D065D2E8E81F7BDE7" +
"434AF80EF81102E9440B99ACB98FBEF8" +
@@ -37,7 +38,8 @@ const (
parseTag string = "sshmoduli"
// The recommended minimum moduli to have available.
recMinMod int = 400
// The
// The minimum bits for filtering. It's generally bits - 1
minBits uint8 = 4095
)
// The header line on the /etc/ssh/moduli file.
@@ -55,7 +57,8 @@ const (
timeFormat string = "20060102150405" // %Y%m%d%H%M%S
)
// For validation
// For validation. Currently unused.
/*
var (
validTypes = []uint8{
0, // Unknown, not tested
@@ -69,3 +72,4 @@ var (
0x04, // Probabilistic Miller-Rabin primality tests.
}
)
*/

View File

@@ -28,33 +28,38 @@ import (
"golang.org/x/crypto/sha3"
)
func getPregen() ([]byte, error) {
// getPregen gets the pregenerated moduli from upstream mirror.
func getPregen() (Moduli, error) {
m := Moduli{}
// get the pregenerated moduli
resp, err := http.Get(pregenURL)
if err != nil {
return nil, err
return m, err
}
if resp.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("returned status code %v: %v", resp.StatusCode, resp.Status))
return m, errors.New(fmt.Sprintf("returned status code %v: %v", resp.StatusCode, resp.Status))
}
defer resp.Body.Close()
b := make([]byte, resp.ContentLength)
if _, err = resp.Body.Read(b); err != nil {
return nil, err
return m, err
}
// and compare the SHA3-512 (NIST) checksum.
s := sha3.New512()
if _, err = s.Write(b); err != nil {
// TODO: return nil instead of b?
return b, err
return m, err
}
goodCksum, err := hex.DecodeString(pregenCksum)
if err != nil {
return nil, err
return m, err
}
// We just compare the bytestrings.
if bytes.Compare(s.Sum(nil), goodCksum) != 0 {
return nil, errors.New("checksums do not match")
return m, errors.New("checksums do not match")
}
return b, nil
if err := Unmarshal(b, m); err != nil {
return m, err
}
return m, nil
}

View File

@@ -1,23 +0,0 @@
/*
SSHSecure - a program to harden OpenSSH from defaults
Copyright (C) 2020 Brent Saner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package moduli
func main() {
}

View File

@@ -50,7 +50,7 @@ func (m *Moduli) Marshal() ([]byte, error) {
}
// marshalEntry is used to parse a specific DH entry into the moduli.
func (m *ModuliEntry) marshalEntry() ([]byte, error) {
func (m *Entry) marshalEntry() ([]byte, error) {
mod := hex.EncodeToString(m.Modulus.Bytes())
s := fmt.Sprintf(
"%v %v %v %v %v %v %v\n",
@@ -68,10 +68,10 @@ func (m *ModuliEntry) marshalEntry() ([]byte, error) {
// Unmarshal writes the Moduli format into m from the /etc/ssh/moduli format in data.
func Unmarshal(data []byte, m Moduli) error {
var lines []string
var entries []ModuliEntry
var entries []Entry
lines = strings.Split(string(data), "\n")
for _, line := range lines {
e := ModuliEntry{}
e := Entry{}
if reSkipLine.MatchString(line) {
continue
}
@@ -85,7 +85,8 @@ func Unmarshal(data []byte, m Moduli) error {
return nil
}
func unmarshalEntry(line []string, m ModuliEntry) error {
func unmarshalEntry(line []string, m Entry) error {
var err error
if len(line) != 7 {
return errors.New("field count mismatch")
}
@@ -117,3 +118,19 @@ func unmarshalEntry(line []string, m ModuliEntry) error {
m.Modulus.SetBytes(modb)
return nil
}
func (m *Moduli) Harden() error {
var entries []Entry
for _, e := range m.Params {
if e.Size >= minBits {
entries = append(entries, e)
}
}
m.Params = entries
if len(m.Params) < recMinMod {
return errors.New("does not meet recommended minimum moduli")
}
return nil
}
// TODO: find way of testing/sieving primes

View File

@@ -26,11 +26,11 @@ import (
// Moduli contains all data needed for generated /etc/ssh/moduli. of ModuliEntry entries.
type Moduli struct {
Header string
Params []ModuliEntry
Params []Entry
}
// Moduli is a struct reflecting the format of a single /etc/ssh/moduli entry. See moduli(5) for details.
type ModuliEntry struct {
type Entry struct {
Time time.Time // YYYYMMDDHHSS
/*
// man 5 moduli: