crypto: change ErrNotRSAPrivateKey to ErrNotRSAPublicKey

Fixes: #19
diff --git a/cover.html b/cover.html
deleted file mode 100644
index 316b917..0000000
--- a/cover.html
+++ /dev/null
@@ -1,268 +0,0 @@
-
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-		<style>
-			body {
-				background: black;
-				color: rgb(80, 80, 80);
-			}
-			body, pre, #legend span {
-				font-family: Menlo, monospace;
-				font-weight: bold;
-			}
-			#topbar {
-				background: black;
-				position: fixed;
-				top: 0; left: 0; right: 0;
-				height: 42px;
-				border-bottom: 1px solid rgb(80, 80, 80);
-			}
-			#content {
-				margin-top: 50px;
-			}
-			#nav, #legend {
-				float: left;
-				margin-left: 10px;
-			}
-			#legend {
-				margin-top: 12px;
-			}
-			#nav {
-				margin-top: 10px;
-			}
-			#legend span {
-				margin: 0 5px;
-			}
-			.cov0 { color: rgb(192, 0, 0) }
-.cov1 { color: rgb(128, 128, 128) }
-.cov2 { color: rgb(116, 140, 131) }
-.cov3 { color: rgb(104, 152, 134) }
-.cov4 { color: rgb(92, 164, 137) }
-.cov5 { color: rgb(80, 176, 140) }
-.cov6 { color: rgb(68, 188, 143) }
-.cov7 { color: rgb(56, 200, 146) }
-.cov8 { color: rgb(44, 212, 149) }
-.cov9 { color: rgb(32, 224, 152) }
-.cov10 { color: rgb(20, 236, 155) }
-
-		</style>
-	</head>
-	<body>
-		<div id="topbar">
-			<div id="nav">
-				<select id="files">
-				
-				<option value="file0">github.com/SermoDigital/jose/base64.go (100.0%)</option>
-				
-				<option value="file1">github.com/SermoDigital/jose/header.go (58.1%)</option>
-				
-				</select>
-			</div>
-			<div id="legend">
-				<span>not tracked</span>
-			
-				<span class="cov0">not covered</span>
-				<span class="cov8">covered</span>
-			
-			</div>
-		</div>
-		<div id="content">
-		
-		<pre class="file" id="file0" >package jose
-
-import "encoding/base64"
-
-// Encoder is satisfied if the type can marshal itself into a valid
-// structure for a JWS.
-type Encoder interface {
-        // Base64 implies T -&gt; JSON -&gt; RawURLEncodingBase64
-        Base64() ([]byte, error)
-}
-
-// Base64Decode decodes a base64-encoded byte slice.
-func Base64Decode(b []byte) ([]byte, error) <span class="cov8" title="1">{
-        buf := make([]byte, base64.RawURLEncoding.DecodedLen(len(b)))
-        n, err := base64.RawURLEncoding.Decode(buf, b)
-        return buf[:n], err
-}</span>
-
-// Base64Encode encodes a byte slice.
-func Base64Encode(b []byte) []byte <span class="cov8" title="1">{
-        buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(b)))
-        base64.RawURLEncoding.Encode(buf, b)
-        return buf
-}</span>
-
-// EncodeEscape base64-encodes a byte slice but escapes it for JSON.
-// It'll return the format: `"base64"`
-func EncodeEscape(b []byte) []byte <span class="cov8" title="1">{
-        buf := make([]byte, base64.RawURLEncoding.EncodedLen(len(b))+2)
-        buf[0] = '"'
-        base64.RawURLEncoding.Encode(buf[1:], b)
-        buf[len(buf)-1] = '"'
-        return buf
-}</span>
-
-// DecodeEscaped decodes a base64-encoded byte slice straight from a JSON
-// structure. It assumes it's in the format: `"base64"`, but can handle
-// cases where it's not.
-func DecodeEscaped(b []byte) ([]byte, error) <span class="cov8" title="1">{
-        if len(b) &gt; 1 &amp;&amp; b[0] == '"' &amp;&amp; b[len(b)-1] == '"' </span><span class="cov8" title="1">{
-                b = b[1 : len(b)-1]
-        }</span>
-        <span class="cov8" title="1">return Base64Decode(b)</span>
-}
-</pre>
-		
-		<pre class="file" id="file1" style="display: none">package jose
-
-import "encoding/json"
-
-// Header implements a JOSE Header with the addition of some helper
-// methods, similar to net/url.Values.
-type Header map[string]interface{}
-
-// Get retrieves the value corresponding with key from the Header.
-func (h Header) Get(key string) interface{} <span class="cov8" title="1">{
-        if h == nil </span><span class="cov8" title="1">{
-                return nil
-        }</span>
-        <span class="cov8" title="1">return h[key]</span>
-}
-
-// Set sets Claims[key] = val. It'll overwrite without warning.
-func (h Header) Set(key string, val interface{}) <span class="cov8" title="1">{
-        h[key] = val
-}</span>
-
-// Del removes the value that corresponds with key from the Header.
-func (h Header) Del(key string) <span class="cov8" title="1">{
-        delete(h, key)
-}</span>
-
-// Has returns true if a value for the given key exists inside the Header.
-func (h Header) Has(key string) bool <span class="cov8" title="1">{
-        _, ok := h[key]
-        return ok
-}</span>
-
-// MarshalJSON implements json.Marshaler for Header.
-func (h Header) MarshalJSON() ([]byte, error) <span class="cov8" title="1">{
-        if h == nil || len(h) == 0 </span><span class="cov0" title="0">{
-                return nil, nil
-        }</span>
-        <span class="cov8" title="1">b, err := json.Marshal(map[string]interface{}(h))
-        if err != nil </span><span class="cov0" title="0">{
-                return nil, err
-        }</span>
-        <span class="cov8" title="1">return EncodeEscape(b), nil</span>
-}
-
-// Base64 implements the Encoder interface.
-func (h Header) Base64() ([]byte, error) <span class="cov0" title="0">{
-        return h.MarshalJSON()
-}</span>
-
-// UnmarshalJSON implements json.Unmarshaler for Header.
-func (h *Header) UnmarshalJSON(b []byte) error <span class="cov8" title="1">{
-        if b == nil </span><span class="cov0" title="0">{
-                return nil
-        }</span>
-
-        <span class="cov8" title="1">b, err := DecodeEscaped(b)
-        if err != nil </span><span class="cov0" title="0">{
-                return err
-        }</span>
-
-        // Since json.Unmarshal calls UnmarshalJSON,
-        // calling json.Unmarshal on *p would be infinitely recursive
-        // A temp variable is needed because &amp;map[string]interface{}(*p) is
-        // invalid Go.
-
-        <span class="cov8" title="1">tmp := map[string]interface{}(*h)
-        if err = json.Unmarshal(b, &amp;tmp); err != nil </span><span class="cov0" title="0">{
-                return err
-        }</span>
-        <span class="cov8" title="1">*h = Header(tmp)
-        return nil</span>
-}
-
-// Protected Headers are base64-encoded after they're marshaled into
-// JSON.
-type Protected Header
-
-// Get retrieves the value corresponding with key from the Protected Header.
-func (p Protected) Get(key string) interface{} <span class="cov0" title="0">{
-        if p == nil </span><span class="cov0" title="0">{
-                return nil
-        }</span>
-        <span class="cov0" title="0">return p[key]</span>
-}
-
-// Set sets Protected[key] = val. It'll overwrite without warning.
-func (p Protected) Set(key string, val interface{}) <span class="cov0" title="0">{
-        p[key] = val
-}</span>
-
-// Del removes the value that corresponds with key from the Protected Header.
-func (p Protected) Del(key string) <span class="cov0" title="0">{
-        delete(p, key)
-}</span>
-
-// Has returns true if a value for the given key exists inside the Protected
-// Header.
-func (p Protected) Has(key string) bool <span class="cov0" title="0">{
-        _, ok := p[key]
-        return ok
-}</span>
-
-// MarshalJSON implements json.Marshaler for Protected.
-func (p Protected) MarshalJSON() ([]byte, error) <span class="cov8" title="1">{
-        b, err := json.Marshal(map[string]interface{}(p))
-        if err != nil </span><span class="cov0" title="0">{
-                return nil, err
-        }</span>
-        <span class="cov8" title="1">return EncodeEscape(b), nil</span>
-}
-
-// Base64 implements the Encoder interface.
-func (p Protected) Base64() ([]byte, error) <span class="cov0" title="0">{
-        b, err := json.Marshal(map[string]interface{}(p))
-        if err != nil </span><span class="cov0" title="0">{
-                return nil, err
-        }</span>
-        <span class="cov0" title="0">return Base64Encode(b), nil</span>
-}
-
-// UnmarshalJSON implements json.Unmarshaler for Protected.
-func (p *Protected) UnmarshalJSON(b []byte) error <span class="cov8" title="1">{
-        var h Header
-        h.UnmarshalJSON(b)
-        *p = Protected(h)
-        return nil
-}</span>
-
-var (
-        _ json.Marshaler   = (Protected)(nil)
-        _ json.Unmarshaler = (*Protected)(nil)
-)
-</pre>
-		
-		</div>
-	</body>
-	<script>
-	(function() {
-		var files = document.getElementById('files');
-		var visible = document.getElementById('file0');
-		files.addEventListener('change', onChange, false);
-		function onChange() {
-			visible.style.display = 'none';
-			visible = document.getElementById(files.value);
-			visible.style.display = 'block';
-			window.scrollTo(0, 0);
-		}
-	})();
-	</script>
-</html>
diff --git a/crypto/rsa_utils.go b/crypto/rsa_utils.go
index 350c394..43aeff3 100644
--- a/crypto/rsa_utils.go
+++ b/crypto/rsa_utils.go
@@ -9,8 +9,9 @@
 
 // Errors specific to rsa_utils.
 var (
-	ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
-	ErrNotRSAPrivateKey    = errors.New("Key is not a valid RSA private key")
+	ErrKeyMustBePEMEncoded = errors.New("invalid key: Key must be PEM encoded PKCS1 or PKCS8 private key")
+	ErrNotRSAPrivateKey    = errors.New("key is not a valid RSA private key")
+	ErrNotRSAPublicKey     = errors.New("key is not a valid RSA public key")
 )
 
 // ParseRSAPrivateKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 private key.
@@ -62,7 +63,7 @@
 	var pkey *rsa.PublicKey
 	var ok bool
 	if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
-		return nil, ErrNotRSAPrivateKey
+		return nil, ErrNotRSAPublicKey
 	}
 
 	return pkey, nil
diff --git a/jws/jws_validate.go b/jws/jws_validate.go
index 1948880..d064113 100644
--- a/jws/jws_validate.go
+++ b/jws/jws_validate.go
@@ -27,40 +27,34 @@
 	return j.VerifyMulti(keys, methods, o)
 }
 
-// IsMultiError returns true if the given error is type MultiError.
+// IsMultiError returns true if the given error is type *MultiError.
 func IsMultiError(err error) bool {
-	_, ok := err.(MultiError)
+	_, ok := err.(*MultiError)
 	return ok
 }
 
 // MultiError is a slice of errors.
 type MultiError []error
 
-func (m MultiError) sanityCheck() error {
-	if m == nil {
-		return nil
-	}
-	return m
-}
-
 // Errors implements the error interface.
-func (m MultiError) Error() string {
-	s, n := "", 0
-	for _, e := range m {
-		if e != nil {
+func (m *MultiError) Error() string {
+	var s string
+	var n int
+	for _, err := range *m {
+		if err != nil {
 			if n == 0 {
-				s = e.Error()
+				s = err.Error()
 			}
 			n++
 		}
 	}
 	switch n {
 	case 0:
-		return "(0 errors)"
+		return ""
 	case 1:
 		return s
 	case 2:
-		return s + " (and 1 other error)"
+		return s + " and 1 other error"
 	}
 	return fmt.Sprintf("%s (and %d other errors)", s, n-1)
 }
@@ -101,7 +95,7 @@
 
 	var o2 SigningOpts
 	if o == nil {
-		o = &SigningOpts{}
+		o = new(SigningOpts)
 	}
 
 	var m MultiError
@@ -112,15 +106,20 @@
 		} else {
 			o2.Inc()
 			if o.Needs(i) {
+				o.ptr++
 				o2.Append(i)
 			}
 		}
 	}
 
-	if err := o.Validate(&o2); err != nil {
-		return err
+	err := o.Validate(&o2)
+	if err != nil {
+		m = append(m, err)
 	}
-	return m.sanityCheck()
+	if len(m) == 0 {
+		return nil
+	}
+	return &m
 }
 
 // SigningOpts is a struct which holds options for validating
@@ -148,30 +147,24 @@
 	_ struct{}
 }
 
-// Append appends x to s's Indices member.
+// Append appends x to s' Indices member.
 func (s *SigningOpts) Append(x int) {
 	s.Indices = append(s.Indices, x)
 }
 
-// Needs returns true if x resides inside s's Indices member
-// for the given index. If true, it increments s's internal
-// index. It's used to match two SigningOpts Indices members.
+// Needs returns true if x resides inside s' Indices member
+// for the given index. It's used to match two SigningOpts Indices members.
 func (s *SigningOpts) Needs(x int) bool {
-	if s.ptr < len(s.Indices) &&
-		s.Indices[s.ptr] == x {
-		s.ptr++
-		return true
-	}
-	return false
+	return s.ptr < len(s.Indices) && s.Indices[s.ptr] == x
 }
 
-// Inc increments s's Number member by one.
+// Inc increments s' Number member by one.
 func (s *SigningOpts) Inc() { s.Number++ }
 
 // Validate returns any errors found while validating the
-// provided SigningOpts. The receiver validates the parameter `have`.
+// provided SigningOpts. The receiver validates |have|.
 // It'll return an error if the passed SigningOpts' Number member is less
-// than s's or if the passed SigningOpts' Indices slice isn't equal to s's.
+// than s' or if the passed SigningOpts' Indices slice isn't equal to s'.
 func (s *SigningOpts) Validate(have *SigningOpts) error {
 	if have.Number < s.Number ||
 		(s.Indices != nil &&
@@ -182,10 +175,7 @@
 }
 
 func eq(a, b []int) bool {
-	if a == nil && b == nil {
-		return true
-	}
-	if a == nil || b == nil || len(a) != len(b) {
+	if len(a) != len(b) {
 		return false
 	}
 	for i := range a {
diff --git a/jws/jwt.go b/jws/jwt.go
index f98edf1..29b75b8 100644
--- a/jws/jwt.go
+++ b/jws/jwt.go
@@ -10,7 +10,10 @@
 
 // NewJWT creates a new JWT with the given claims.
 func NewJWT(claims Claims, method crypto.SigningMethod) jwt.JWT {
-	j := New(claims, method).(*jws)
+	j, ok := New(claims, method).(*jws)
+	if !ok {
+		panic("jws.NewJWT: runtime panic: New(...).(*jws) != true")
+	}
 	j.sb[0].protected.Set("typ", "JWT")
 	j.isJWT = true
 	return j
@@ -98,8 +101,7 @@
 	}
 }
 
-// NewValidator returns a pointer to a jwt.Validator structure containing
-// the info to be used in the validation of a JWT.
+// NewValidator returns a jwt.Validator.
 func NewValidator(c Claims, exp, nbf time.Duration, fn func(Claims) error) *jwt.Validator {
 	return &jwt.Validator{
 		Expected: jwt.Claims(c),