Skip to content

Commit

Permalink
Replace MD5 in dgraph cert ls (dgraph-io#3254)
Browse files Browse the repository at this point in the history
* Change cert ls command to output SHA-256 digests instead of MD5.
  • Loading branch information
codexnull authored and dna2github committed Jul 19, 2019
1 parent 8083392 commit b15f0e8
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 35 deletions.
29 changes: 22 additions & 7 deletions dgraph/cmd/cert/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
package cert

import (
"crypto/md5"
"crypto/rsa"
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
Expand All @@ -33,7 +33,7 @@ type certInfo struct {
commonName string
serialNumber string
verifiedCA string
md5sum string
digest string
expireDate time.Time
hosts []string
fileMode string
Expand Down Expand Up @@ -76,10 +76,9 @@ func getFileInfo(file string) *certInfo {
}

if key, ok := cert.PublicKey.(*rsa.PublicKey); ok {
h := md5.Sum(key.N.Bytes())
info.md5sum = fmt.Sprintf("%X", h[:])
info.digest = getHexDigest(key.N.Bytes())
} else {
info.md5sum = "Invalid RSA public key"
info.digest = "Invalid RSA public key"
}

if file != defaultCACert {
Expand Down Expand Up @@ -115,8 +114,7 @@ func getFileInfo(file string) *certInfo {
info.err = err
return &info
}
h := md5.Sum(key.PublicKey.N.Bytes())
info.md5sum = fmt.Sprintf("%X", h[:])
info.digest = getHexDigest(key.PublicKey.N.Bytes())

default:
info.err = fmt.Errorf("Unsupported file")
Expand All @@ -125,6 +123,23 @@ func getFileInfo(file string) *certInfo {
return &info
}

// getHexDigest returns a SHA-256 hex digest broken up into 32-bit chunks
// so that they easier to compare visually
// e.g. 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5
func getHexDigest(data []byte) string {
const groupSizeBytes = 4

digest := sha256.Sum256(data)
groups := len(digest) / groupSizeBytes
hex := fmt.Sprintf("%0*X", groupSizeBytes*2, digest[0:groupSizeBytes])
for i := 1; i < groups; i++ {
hex += fmt.Sprintf(" %0*X", groupSizeBytes*2,
digest[i*groupSizeBytes:(i+1)*groupSizeBytes])
}

return hex
}

// getDirFiles walks dir and collects information about the files contained.
// Returns the list of files, or an error otherwise.
func getDirFiles(dir string) ([]*certInfo, error) {
Expand Down
12 changes: 6 additions & 6 deletions dgraph/cmd/cert/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,21 @@ func listCerts() error {
}
fmt.Printf("%s %s - %s\n", f.fileMode, f.fileName, f.commonName)
if f.issuerName != "" {
fmt.Printf("%10s: %s\n", "Issuer", f.issuerName)
fmt.Printf("%14s: %s\n", "Issuer", f.issuerName)
}
if f.verifiedCA != "" {
fmt.Printf("%10s: %s\n", "CA Verify", f.verifiedCA)
fmt.Printf("%14s: %s\n", "CA Verify", f.verifiedCA)
}
if f.serialNumber != "" {
fmt.Printf("%10s: %s\n", "S/N", f.serialNumber)
fmt.Printf("%14s: %s\n", "S/N", f.serialNumber)
}
if !f.expireDate.IsZero() {
fmt.Printf("%10s: %x\n", "Expiration", f)
fmt.Printf("%14s: %x\n", "Expiration", f)
}
if f.hosts != nil {
fmt.Printf("%10s: %s\n", "Hosts", strings.Join(f.hosts, ", "))
fmt.Printf("%14s: %s\n", "Hosts", strings.Join(f.hosts, ", "))
}
fmt.Printf("%10s: %s\n\n", "MD5 hash", f.md5sum)
fmt.Printf("%14s: %s\n\n", "SHA-256 Digest", f.digest)
}

return nil
Expand Down
46 changes: 24 additions & 22 deletions wiki/content/deploy/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1331,41 +1331,43 @@ Example of command output:

```sh
-rw-r--r-- ca.crt - Dgraph Root CA certificate
Issuer: Dgraph Labs, Inc.
S/N: 3e468ac77ecd5017
Expiration: 23 Sep 28 19:10 UTC
MD5 hash: 85B533D86B0DD689B9DBDAD6755B702F
Issuer: Dgraph Labs, Inc.
S/N: 043c4d8fdd347f06
Expiration: 02 Apr 29 16:56 UTC
SHA-256 Digest: 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5

-r-------- ca.key - Dgraph Root CA key
MD5 hash: 85B533D86B0DD689B9DBDAD6755B702F
SHA-256 Digest: 4A2B0F0F 716BF5B6 C603E01A 6229D681 0B2AFDC5 CADF5A0D 17D59299 116119E5

-rw-r--r-- client.srfrog.crt - Dgraph client certificate: srfrog
Issuer: Dgraph Labs, Inc.
CA Verify: PASSED
S/N: 55cedf3c8606d98e
Expiration: 25 Sep 23 19:25 UTC
MD5 hash: 445DCB276E29FA1000F79CAC376569BA
-rw-r--r-- client.admin.crt - Dgraph client certificate: admin
Issuer: Dgraph Labs, Inc.
CA Verify: PASSED
S/N: 297e4cb4f97c71f9
Expiration: 03 Apr 24 17:29 UTC
SHA-256 Digest: D23EFB61 DE03C735 EB07B318 DB70D471 D3FE8556 B15D084C 62675857 788DF26C

-rw------- client.srfrog.key - Dgraph Client key
MD5 hash: 445DCB276E29FA1000F79CAC376569BA
-rw------- client.admin.key - Dgraph Client key
SHA-256 Digest: D23EFB61 DE03C735 EB07B318 DB70D471 D3FE8556 B15D084C 62675857 788DF26C

-rw-r--r-- node.crt - Dgraph Node certificate
Issuer: Dgraph Labs, Inc.
CA Verify: PASSED
S/N: 75aeb1ccd9a6f3fd
Expiration: 25 Sep 23 19:39 UTC
Hosts: localhost
MD5 hash: FA0FFC88F7AA654575CD48A493C3D65A
Issuer: Dgraph Labs, Inc.
CA Verify: PASSED
S/N: 795ff0e0146fdb2d
Expiration: 03 Apr 24 17:00 UTC
Hosts: 104.25.165.23, 2400:cb00:2048:1::6819:a417, localhost, dgraph.io
SHA-256 Digest: 7E243ED5 3286AE71 B9B4E26C 5B2293DA D3E7F336 1B1AFFA7 885E8767 B1A84D28

-rw------- node.key - Dgraph Node key
MD5 hash: FA0FFC88F7AA654575CD48A493C3D65A
SHA-256 Digest: 7E243ED5 3286AE71 B9B4E26C 5B2293DA D3E7F336 1B1AFFA7 885E8767 B1A84D28
```

Important points:

* The cert/key pairs should always have matching MD5 hashes. Otherwise, the cert(s) must be regenerated. If the Root CA pair differ, all cert/key must be regenerated; the flag `--force` can help.
* The cert/key pairs should always have matching SHA-256 digests. Otherwise, the cert(s) must be
regenerated. If the Root CA pair differ, all cert/key must be regenerated; the flag `--force`
can help.
* All certificates must pass Dgraph CA verification.
* All key files should have the least access permissions, specially the `ca.key`, but be readable.
* All key files should have the least access permissions, especially the `ca.key`, but be readable.
* Key files won't be overwritten if they have limited access, even with `--force`.
* Node certificates are only valid for the hosts listed.
* Client certificates are only valid for the named client/user.
Expand Down

0 comments on commit b15f0e8

Please sign in to comment.