github.com/readium/readium-lcp-server@v0.0.0-20240509124024-799e77a0bbd6/sign/sign_test.go (about)

     1  // Copyright (c) 2016 Readium Foundation
     2  //
     3  // Redistribution and use in source and binary forms, with or without modification,
     4  // are permitted provided that the following conditions are met:
     5  //
     6  // 1. Redistributions of source code must retain the above copyright notice, this
     7  //    list of conditions and the following disclaimer.
     8  // 2. Redistributions in binary form must reproduce the above copyright notice,
     9  //    this list of conditions and the following disclaimer in the documentation and/or
    10  //    other materials provided with the distribution.
    11  // 3. Neither the name of the organization nor the names of its contributors may be
    12  //    used to endorse or promote products derived from this software without specific
    13  //    prior written permission
    14  //
    15  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    16  // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    17  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    18  // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
    19  // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    20  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    21  // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    22  // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    23  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    24  // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    25  
    26  package sign
    27  
    28  import (
    29  	"crypto"
    30  	"crypto/ecdsa"
    31  	"crypto/rsa"
    32  	"crypto/sha256"
    33  	"crypto/tls"
    34  	"math/big"
    35  	"testing"
    36  )
    37  
    38  func TestSigningRSA(t *testing.T) {
    39  	cert, err := tls.LoadX509KeyPair("cert/sample_rsa.crt", "cert/sample_rsa.pem")
    40  	if err != nil {
    41  		t.Error("Couldn't load sample certificate ", err)
    42  		t.FailNow()
    43  	}
    44  
    45  	signer, err := NewSigner(&cert)
    46  	if err != nil {
    47  		t.Error(err)
    48  		t.FailNow()
    49  	}
    50  
    51  	input := map[string]string{"test": "test"}
    52  	sig, err := signer.Sign(input)
    53  
    54  	if expected := "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; sig.Algorithm != expected {
    55  		t.Errorf("Expected '%s', got '%s'", expected, sig.Algorithm)
    56  	}
    57  
    58  	canon, _ := Canon(input)
    59  	hashed := sha256.Sum256(canon)
    60  
    61  	if privKey, ok := cert.PrivateKey.(*rsa.PrivateKey); ok {
    62  		if err := rsa.VerifyPKCS1v15(&privKey.PublicKey, crypto.SHA256, hashed[:], sig.Value); err != nil {
    63  			t.Error("Expected the signature to be valid, got", err)
    64  		}
    65  	}
    66  }
    67  
    68  func TestSigningECDSA(t *testing.T) {
    69  	cert, err := tls.LoadX509KeyPair("cert/sample_ecdsa.crt", "cert/sample_ecdsa.pem")
    70  	if err != nil {
    71  		t.Error("Couldn't load sample certificate ", err)
    72  		t.FailNow()
    73  	}
    74  
    75  	signer, err := NewSigner(&cert)
    76  	if err != nil {
    77  		t.Error(err)
    78  		t.FailNow()
    79  	}
    80  	input := map[string]string{"test": "test"}
    81  	sig, err := signer.Sign(input)
    82  
    83  	if err != nil {
    84  		t.Error(err)
    85  	}
    86  
    87  	if expected := "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"; sig.Algorithm != expected {
    88  		t.Errorf("Expected '%s', got '%s'", expected, sig.Algorithm)
    89  	}
    90  
    91  	r, s := getParamsFromECDSASignature(sig.Value)
    92  
    93  	canon, _ := Canon(input)
    94  	hashed := sha256.Sum256(canon)
    95  
    96  	if privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey); ok {
    97  		if publicKey, ok := privKey.Public().(*ecdsa.PublicKey); ok {
    98  			if !ecdsa.Verify(publicKey, hashed[:], r, s) {
    99  				t.Error("Expected the signature to be valid")
   100  			}
   101  		}
   102  	}
   103  }
   104  
   105  func getParamsFromECDSASignature(b []byte) (*big.Int, *big.Int) {
   106  	half := len(b) / 2
   107  	r := big.NewInt(0)
   108  	s := big.NewInt(0)
   109  
   110  	r.SetBytes(b[0:half])
   111  	s.SetBytes(b[half:])
   112  
   113  	return r, s
   114  }