...

Source file src/github.com/ory/fosite/handler/openid/helper.go

Documentation: github.com/ory/fosite/handler/openid

     1  /*
     2   * Copyright © 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
     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   * @author		Aeneas Rekkas <aeneas+oss@aeneas.io>
    17   * @copyright 	2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
    18   * @license 	Apache-2.0
    19   *
    20   */
    21  
    22  package openid
    23  
    24  import (
    25  	"bytes"
    26  	"context"
    27  	"crypto/sha256"
    28  	"crypto/sha512"
    29  	"encoding/base64"
    30  	"strconv"
    31  
    32  	"github.com/ory/fosite"
    33  )
    34  
    35  type IDTokenHandleHelper struct {
    36  	IDTokenStrategy OpenIDConnectTokenStrategy
    37  }
    38  
    39  func (i *IDTokenHandleHelper) GetAccessTokenHash(ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder) string {
    40  	token := responder.GetAccessToken()
    41  	// The session should always be a openid.Session but best to safely cast
    42  	if session, ok := requester.GetSession().(Session); ok {
    43  		val, err := i.ComputeHash(ctx, session, token)
    44  		if err != nil {
    45  			// this should never happen
    46  			panic(err)
    47  		}
    48  
    49  		return val
    50  	}
    51  
    52  	buffer := bytes.NewBufferString(token)
    53  	hash := sha256.New()
    54  	// sha256.digest.Write() always returns nil for err, the panic should never happen
    55  	_, err := hash.Write(buffer.Bytes())
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  	hashBuf := bytes.NewBuffer(hash.Sum([]byte{}))
    60  
    61  	return base64.RawURLEncoding.EncodeToString(hashBuf.Bytes()[:hashBuf.Len()/2])
    62  }
    63  
    64  func (i *IDTokenHandleHelper) generateIDToken(ctx context.Context, fosr fosite.Requester) (token string, err error) {
    65  	token, err = i.IDTokenStrategy.GenerateIDToken(ctx, fosr)
    66  	if err != nil {
    67  		return "", err
    68  	}
    69  
    70  	return token, nil
    71  }
    72  
    73  func (i *IDTokenHandleHelper) IssueImplicitIDToken(ctx context.Context, ar fosite.Requester, resp fosite.AuthorizeResponder) error {
    74  	token, err := i.generateIDToken(ctx, ar)
    75  	if err != nil {
    76  		return err
    77  	}
    78  	resp.AddParameter("id_token", token)
    79  	return nil
    80  }
    81  
    82  func (i *IDTokenHandleHelper) IssueExplicitIDToken(ctx context.Context, ar fosite.Requester, resp fosite.AccessResponder) error {
    83  	token, err := i.generateIDToken(ctx, ar)
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	resp.SetExtra("id_token", token)
    89  	return nil
    90  }
    91  
    92  // ComputeHash computes the hash using the alg defined in the id_token header
    93  func (i *IDTokenHandleHelper) ComputeHash(ctx context.Context, sess Session, token string) (string, error) {
    94  	var err error
    95  	hash := sha256.New()
    96  	if alg, ok := sess.IDTokenHeaders().Get("alg").(string); ok && len(alg) > 2 {
    97  		if hashSize, err := strconv.Atoi(alg[2:]); err == nil {
    98  			if hashSize == 384 {
    99  				hash = sha512.New384()
   100  			} else if hashSize == 512 {
   101  				hash = sha512.New()
   102  			}
   103  		}
   104  	}
   105  
   106  	buffer := bytes.NewBufferString(token)
   107  	_, err = hash.Write(buffer.Bytes())
   108  	if err != nil {
   109  		return "", err
   110  	}
   111  	hashBuf := bytes.NewBuffer(hash.Sum([]byte{}))
   112  
   113  	return base64.RawURLEncoding.EncodeToString(hashBuf.Bytes()[:hashBuf.Len()/2]), nil
   114  }
   115  

View as plain text