cshash

package module
v0.0.0-...-200c9ca Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2020 License: MIT Imports: 8 Imported by: 1

README

CSHash

Certificate Structure Hash library and command line tool in Go.

Certificate Structure Hash (CSHash) is an algorithm to fingerprint the structure of X.509 (TLS) certificates. This repository contains both the source code to use CSHash as command line tool or as a go library.

It can be used to identify different certificates generated using the same libraries or scripts, since such certificates tend to have similar structures but different contents. The main use-case that we developed CSHash for is to fingerprint malicious certificates.

The CSHash algorithm takes a raw certificate as input in DER or PEM (base64 encoded DER) format and deterministically produces a 128-bit digest that is unique to the certificate structure. The algorithm parses the certificate and maps it to a JSON-like string that captures the certificate structure but abstracts away the contents. Then, an md5 hash is computed over that string to produce a fixed-length output.

Building

The following command requires the $GOPATH environment variable to be set. It will download the package to your workspace.

$ go get github.com/KTiago/cshash

You can build the project with the following commands.

$ cd $GOPATH/src/github.com/KTiago/cshash
$ make build

This will create the executable cshash in the folder $GOPATH/src/github.com/KTiago/cshash. You are ready to compute the CSHash of a certificate.

$ ./cshash -i example.pem
759eedf155aa5a24e49bd1f00eea5bfb

Usage

To display a guide on the usage of CSHash run the following command.

$ ./cshash --help

Example

Below is the extracted structure of an example self-signed certificate for "C=XX, L=Default City, O=Default Company Ltd" in an JSON-like format. The CSHash is the md5 hash over the below string where spaces and line returns have been removed.

$ ./cshash -i example.pem --struct --pretty
{
  SEQUENCE: {
    SEQUENCE: {
      VERSION: {
        INTEGER: ∅
      },
      INTEGER: ∅,
      SEQUENCE: {
        OBJECT_IDENTIFIER: 1.2.840.113549.1.1.11,
        NULL: ∅
      },
      SEQUENCE: {
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.6,
            PRINTABLE_STRING: ∅
          }
        },
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.7,
            UTF8_STRING: ∅
          }
        },
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.10,
            UTF8_STRING: ∅
          }
        }
      },
      SEQUENCE: {
        UTC_TIME: ∅,
        UTC_TIME: ∅
      },
      SEQUENCE: {
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.6,
            PRINTABLE_STRING: ∅
          }
        },
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.7,
            UTF8_STRING: ∅
          }
        },
        SET: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.4.10,
            UTF8_STRING: ∅
          }
        }
      },
      SEQUENCE: {
        SEQUENCE: {
          OBJECT_IDENTIFIER: 1.2.840.113549.1.1.1,
          NULL: ∅
        },
        BIT_STRING: ∅
      },
      EXTENSION: {
        SEQUENCE: {
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.29.14,
            OCTET_STRING: ∅
          },
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.29.35,
            OCTET_STRING: ∅
          },
          SEQUENCE: {
            OBJECT_IDENTIFIER: 2.5.29.19,
            BOOLEAN: ∅,
            OCTET_STRING: ∅
          }
        }
      }
    },
    SEQUENCE: {
      OBJECT_IDENTIFIER: 1.2.840.113549.1.1.11,
      NULL: ∅
    },
    BIT_STRING: ∅
  }
}

Documentation

Index

Constants

View Source
const (
	// Types
	BOOLEAN           = 0x01
	INTEGER           = 0x02
	BIT_STRING        = 0x03
	OCTET_STRING      = 0x04
	NULL              = 0x05
	OBJECT_IDENTIFIER = 0x06
	OBJECT_DESCRIPTOR = 0x07
	EXTERNAL          = 0x08
	REAL              = 0x09
	UTF8_STRING       = 0x0C
	PRINTABLE_STRING  = 0x13
	IA5STRING         = 0x16
	UTC_TIME          = 0x17
	GENERALIZED_TIME  = 0x18
	SEQUENCE          = 0x30
	SET               = 0x31
	VERSION           = 0xA0
	ISSUER_UNIQUE_ID  = 0xA1
	SUBJECT_UNIQUE_ID = 0xA2
	EXTENSION         = 0xA3

	// Object identifiers used in X.509 certificates
	KEY_USAGE               = 0x551D0F
	EXT_KEY_USAGE           = 0x551D25
	BASIC_CONSTRAINTS       = 0x551D13
	AUTHORITY_INFO_ACCESS   = 0x2B06010505070101
	CERTIFICATE_POLICIES    = 0x551D20
	CRL_DISTRIBUTION_POINTS = 0x0551D1F
)

Variables

View Source
var TYPE = map[int]string{
	BOOLEAN:           `"BOOLEAN"`,
	INTEGER:           `"INTEGER"`,
	BIT_STRING:        `"BIT_STRING"`,
	OCTET_STRING:      `"OCTET_STRING"`,
	NULL:              `"NULL"`,
	OBJECT_IDENTIFIER: `"OBJECT_IDENTIFIER"`,
	OBJECT_DESCRIPTOR: `"OBJECT_DESCRIPTOR"`,
	EXTERNAL:          `"EXTERNAL"`,
	REAL:              `"REAL"`,
	UTF8_STRING:       `"UTF8_STRING"`,
	PRINTABLE_STRING:  `"PRINTABLE_STRING"`,
	IA5STRING:         `"IA5STRING"`,
	UTC_TIME:          `"UTC_TIME"`,
	GENERALIZED_TIME:  `"GENERALIZED_TIME"`,
	SEQUENCE:          `"SEQUENCE"`,
	SET:               `"SET"`,
	VERSION:           `"VERSION"`,
	ISSUER_UNIQUE_ID:  `"ISSUER_UNIQUE_ID"`,
	SUBJECT_UNIQUE_ID: `"SUBJECT_UNIQUE_ID"`,
	EXTENSION:         `"EXTENSION"`,
}

Functions

func Fingerprint

func Fingerprint(certDER []byte) string

func OIDToString

func OIDToString(bytes []byte) string

func PEMToBase64

func PEMToBase64(cert string) string

func PEMToDER

func PEMToDER(cert string) ([]byte, error)

func ParseStructure

func ParseStructure(certDER []byte, prettyPrint bool) (string, error)

func ParseStructureRec

func ParseStructureRec(bytes []byte) (structure []string, err error)

Given the bytes of a DER encoded X.509 certificate, returns an array of bytes that is unique to the ASN1 structure of the certificate and does not depend on the contents of the certificate.

Types

type Byte

type Byte byte

type ParseError

type ParseError struct {
	Msg string
}

func (*ParseError) Error

func (e *ParseError) Error() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL