...

Source file src/github.com/sassoftware/relic/lib/signxap/verify.go

Documentation: github.com/sassoftware/relic/lib/signxap

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package signxap
    18  
    19  import (
    20  	"crypto"
    21  	"crypto/hmac"
    22  	"encoding/binary"
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  
    27  	"github.com/sassoftware/relic/lib/authenticode"
    28  	"github.com/sassoftware/relic/lib/pkcs7"
    29  	"github.com/sassoftware/relic/lib/pkcs9"
    30  	"github.com/sassoftware/relic/lib/x509tools"
    31  	"github.com/sassoftware/relic/signers/sigerrors"
    32  )
    33  
    34  type XapSignature struct {
    35  	pkcs9.TimestampedSignature
    36  	Hash crypto.Hash
    37  }
    38  
    39  func Verify(r io.ReaderAt, size int64, skipDigests bool) (*XapSignature, error) {
    40  	var tr xapTrailer
    41  	if err := binary.Read(io.NewSectionReader(r, size-10, 10), binary.LittleEndian, &tr); err != nil {
    42  		return nil, err
    43  	}
    44  	if tr.Magic != trailerMagic {
    45  		var zipMagic uint32
    46  		if err := binary.Read(io.NewSectionReader(r, size-22, 4), binary.LittleEndian, &zipMagic); err != nil {
    47  			return nil, err
    48  		}
    49  		if zipMagic == 0x06054b50 {
    50  			return nil, sigerrors.NotSignedError{Type: "XAP"}
    51  		}
    52  		return nil, errors.New("invalid xap file")
    53  	}
    54  	size -= int64(tr.TrailerSize) + 10
    55  	var hdr xapHeader
    56  	if err := binary.Read(io.NewSectionReader(r, size, 8), binary.LittleEndian, &hdr); err != nil {
    57  		return nil, err
    58  	}
    59  	if hdr.SignatureSize != tr.TrailerSize-8 {
    60  		return nil, errors.New("invalid xap file")
    61  	}
    62  	blob := make([]byte, hdr.SignatureSize)
    63  	if n, err := r.ReadAt(blob, size+8); err != nil {
    64  		return nil, err
    65  	} else if n < len(blob) {
    66  		return nil, io.ErrUnexpectedEOF
    67  	}
    68  	psd, err := pkcs7.Unmarshal(blob)
    69  	if err != nil {
    70  		return nil, fmt.Errorf("invalid signature: %s", err)
    71  	}
    72  	if !psd.Content.ContentInfo.ContentType.Equal(authenticode.OidSpcIndirectDataContent) {
    73  		return nil, fmt.Errorf("invalid signature: %s", "not an authenticode signature")
    74  	}
    75  	pksig, err := psd.Content.Verify(nil, false)
    76  	if err != nil {
    77  		return nil, fmt.Errorf("invalid signature: %s", err)
    78  	}
    79  	ts, err := pkcs9.VerifyOptionalTimestamp(pksig)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	indirect := new(authenticode.SpcIndirectDataContentMsi)
    84  	if err := psd.Content.ContentInfo.Unmarshal(indirect); err != nil {
    85  		return nil, fmt.Errorf("invalid signature: %s", err)
    86  	}
    87  	hash, err := x509tools.PkixDigestToHashE(indirect.MessageDigest.DigestAlgorithm)
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  	if !skipDigests {
    92  		d := hash.New()
    93  		if _, err := io.Copy(d, io.NewSectionReader(r, 0, size)); err != nil {
    94  			return nil, err
    95  		}
    96  		calc := d.Sum(nil)
    97  		expected := indirect.MessageDigest.Digest
    98  		if !hmac.Equal(calc, expected) {
    99  			return nil, fmt.Errorf("digest mismatch: calculated %x != found %x", calc, expected)
   100  		}
   101  	}
   102  	return &XapSignature{TimestampedSignature: ts, Hash: hash}, nil
   103  }
   104  

View as plain text