...

Source file src/github.com/google/certificate-transparency-go/fixchain/hash.go

Documentation: github.com/google/certificate-transparency-go/fixchain

     1  // Copyright 2016 Google LLC. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package fixchain
    16  
    17  import (
    18  	"crypto/sha256"
    19  	"sort"
    20  
    21  	"github.com/google/certificate-transparency-go/x509"
    22  )
    23  
    24  const hashSize = sha256.Size
    25  
    26  var newHash = sha256.New
    27  
    28  func hash(c *x509.Certificate) (hash [hashSize]byte) {
    29  	copy(hash[:], newHash().Sum(c.Raw))
    30  	return
    31  }
    32  
    33  func hashChain(ch []*x509.Certificate) (hash [hashSize]byte) {
    34  	h := newHash()
    35  	for _, c := range ch {
    36  		h.Write(newHash().Sum(c.Raw))
    37  	}
    38  	copy(hash[:], h.Sum(nil))
    39  	return
    40  }
    41  
    42  // hashBag hashes all of the certs in the chain, irrespective of their order.
    43  // Chains containing the same certs in the same order with no duplicates will
    44  // result in the same hash. Chains containing the same certs in different orders
    45  // with no duplicates will result in the same hash.  Chains containing the same
    46  // certs (either in the same order or in different orders) that contain exactly
    47  // the same duplicated certs, will result in the same hash.  If chains contain
    48  // the same certs (either in the same order or in different orders) and some
    49  // certs are duplicated, but the specific certs that are duplicated differ
    50  // and/or the number of times they are duplicated differ, these chains will
    51  // result in different hashes.
    52  func hashBag(chain []*x509.Certificate) [hashSize]byte {
    53  	b := bag{certs: make([]*x509.Certificate, len(chain))}
    54  	copy(b.certs, chain)
    55  	sort.Sort(b)
    56  	return hashChain(b.certs)
    57  }
    58  
    59  // bag is a collection of certificates that can contain duplicates.
    60  // Applying sort will order them by their raw representation.
    61  type bag struct {
    62  	certs []*x509.Certificate
    63  }
    64  
    65  // Len implements sort.Sort(data Interface) for bag.
    66  func (b bag) Len() int { return len(b.certs) }
    67  
    68  // Less implements sort.Sort(data Interface) for bag.
    69  func (b bag) Less(i, j int) bool {
    70  	ci := b.certs[i].Raw
    71  	cj := b.certs[j].Raw
    72  	if len(ci) != len(cj) {
    73  		return len(ci) < len(cj)
    74  	}
    75  	for n := range ci {
    76  		if ci[n] < cj[n] {
    77  			return true
    78  		}
    79  		if ci[n] > cj[n] {
    80  			return false
    81  		}
    82  	}
    83  	return false
    84  }
    85  
    86  // Swap implements sort.Sort(data Interface) for bag.
    87  func (b bag) Swap(i, j int) {
    88  	t := b.certs[i]
    89  	b.certs[i] = b.certs[j]
    90  	b.certs[j] = t
    91  }
    92  

View as plain text