...

Source file src/github.com/sassoftware/relic/signers/ps/signer.go

Documentation: github.com/sassoftware/relic/signers/ps

     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 ps
    18  
    19  // Sign Microsoft PowerShell scripts, modules, and other bits that can be signed
    20  
    21  import (
    22  	"errors"
    23  	"io"
    24  	"os"
    25  	"path/filepath"
    26  	"strings"
    27  
    28  	"github.com/sassoftware/relic/lib/authenticode"
    29  	"github.com/sassoftware/relic/lib/certloader"
    30  	"github.com/sassoftware/relic/lib/x509tools"
    31  	"github.com/sassoftware/relic/signers"
    32  )
    33  
    34  var PsSigner = &signers.Signer{
    35  	Name:      "ps",
    36  	CertTypes: signers.CertTypeX509,
    37  	TestPath:  testPath,
    38  	Transform: transform,
    39  	Sign:      sign,
    40  	Verify:    verify,
    41  }
    42  
    43  func init() {
    44  	PsSigner.Flags().String("ps-style", "", "(Powershell) signature type")
    45  	signers.Register(PsSigner)
    46  }
    47  
    48  func testPath(fp string) bool {
    49  	_, ok := authenticode.GetSigStyle(fp)
    50  	return ok
    51  }
    52  
    53  func transform(f *os.File, opts signers.SignOpts) (signers.Transformer, error) {
    54  	// detect signature style and explicitly set it for the request
    55  	argStyle := opts.Flags.GetString("ps-style")
    56  	if argStyle == "" {
    57  		argStyle = filepath.Ext(opts.Path)
    58  	}
    59  	opts.Flags.Values["ps-style"] = argStyle
    60  	return signers.DefaultTransform(f), nil
    61  }
    62  
    63  func sign(r io.Reader, cert *certloader.Certificate, opts signers.SignOpts) ([]byte, error) {
    64  	argStyle := opts.Flags.GetString("ps-style")
    65  	if argStyle == "" {
    66  		argStyle = opts.Path
    67  	}
    68  	style, err := getStyle(argStyle)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	digest, err := authenticode.DigestPowershell(r, style, opts.Hash)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	patch, ts, err := digest.Sign(opts.Context(), cert)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	opts.Audit.SetCounterSignature(ts.CounterSignature)
    81  	return opts.SetBinPatch(patch)
    82  }
    83  
    84  func verify(f *os.File, opts signers.VerifyOpts) ([]*signers.Signature, error) {
    85  	style, err := getStyle(f.Name())
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	ts, err := authenticode.VerifyPowershell(f, style, opts.NoDigests)
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	hash, _ := x509tools.PkixDigestToHash(ts.SignerInfo.DigestAlgorithm)
    94  	return []*signers.Signature{&signers.Signature{
    95  		Hash:          hash,
    96  		X509Signature: ts,
    97  	}}, nil
    98  }
    99  
   100  func getStyle(name string) (authenticode.PsSigStyle, error) {
   101  	style, ok := authenticode.GetSigStyle(name)
   102  	if !ok {
   103  		return 0, errors.New("unknown powershell style, expected: " + strings.Join(authenticode.AllSigStyles(), " "))
   104  	}
   105  	return style, nil
   106  }
   107  

View as plain text