// SignCertificateOneRegion given a public key, identity token and forceCommand, invoke the sshrimp-ca lambda function
SignCertificateOneRegion given a public key, identity token and forceCommand, invoke the sshrimp-ca lambda function
// SignCertificateOneRegion given a public key identity token and forceCommand invoke the sshrimp - ca lambda function
func SignCertificateOneRegion(publicKey ssh.PublicKey, token string, forceCommand string, region string, c *config.SSHrimp) (*ssh.Certificate, error) {
	initialSession := session.Must(session.NewSession())
	svc := sts.New(initialSession)
	roleArn := "arn:aws:iam::" + strconv.Itoa(c.CertificateAuthority.AccountID) + ":role/sshrimp-ca-" + region
	tokenUsernameClaim := DecodeAndReturnUsernameClaim(token, c.CertificateAuthority.UsernameClaim)
	awsCred, err := svc.AssumeRoleWithWebIdentity(&sts.AssumeRoleWithWebIdentityInput{
		RoleArn:          aws.String(roleArn),
		RoleSessionName:  aws.String(tokenUsernameClaim),
		WebIdentityToken: aws.String(token),
		DurationSeconds:  aws.Int64(900),
	})
	if err != nil {
		return nil, fmt.Errorf("Unable to perform assume-role-with-web-identity: %v", err)
	}
	creds := credentials.NewStaticCredentials(*awsCred.Credentials.AccessKeyId, *awsCred.Credentials.SecretAccessKey, *awsCred.Credentials.SessionToken)
	tempSession := session.Must(session.NewSession(&aws.Config{
		Region:      aws.String(region),
		Credentials: creds,
	}))
	lambdaService := lambda.New(tempSession)
	payload, err := json.Marshal(SSHrimpEvent{
		PublicKey:    string(ssh.MarshalAuthorizedKey(publicKey)),
		Token:        token,
		ForceCommand: forceCommand,
	})
	if err != nil {
		return nil, err
	}
	result, err := lambdaService.Invoke(&lambda.InvokeInput{
		FunctionName: aws.String(c.CertificateAuthority.FunctionName),
		Payload:      payload,
	})
	if err != nil {
		return nil, err
	}
	if *result.StatusCode != 200 {
		return nil, fmt.Errorf("sshrimp returned status code %d", *result.StatusCode)
	}
	sshrimpResult := SSHrimpResult{}
	err = json.Unmarshal(result.Payload, &sshrimpResult)
	if err != nil {
		return nil, errors.Wrap(err, "failed to parse json response from sshrimp-ca")
	}
	if sshrimpResult.ErrorType != "" || sshrimpResult.ErrorMessage != "" {
		return nil, fmt.Errorf("%s: %s", sshrimpResult.ErrorType, sshrimpResult.ErrorMessage)
	}
	cert, _, _, _, err := ssh.ParseAuthorizedKey([]byte(sshrimpResult.Certificate))
	if err != nil {
		return nil, err
	}
	return cert.(*ssh.Certificate), nil
}
func SignCertificateOneRegion ( publicKey ssh . PublicKey , token string , forceCommand string , region string , c * config . SSHrimp ) ( * ssh . Certificate , error ) { initialSession := session . Must ( session . NewSession ( ) ) svc := sts . New ( initialSession ) roleArn := " " + strconv . Itoa ( c . CertificateAuthority . AccountID ) + " " + region tokenUsernameClaim := DecodeAndReturnUsernameClaim ( token , c . CertificateAuthority . UsernameClaim ) awsCred , err := svc . AssumeRoleWithWebIdentity ( & sts . AssumeRoleWithWebIdentityInput { RoleArn : aws . String ( roleArn ) , RoleSessionName : aws . String ( tokenUsernameClaim ) , WebIdentityToken : aws . String ( token ) , DurationSeconds : aws . Int64 ( 900 ) , } ) if err != nil { return nil , fmt . Errorf ( " " , err ) } creds := credentials . NewStaticCredentials ( * awsCred . Credentials . AccessKeyId , * awsCred . Credentials . SecretAccessKey , * awsCred . Credentials . SessionToken ) tempSession := session . Must ( session . NewSession ( & aws . Config { Region : aws . String ( region ) , Credentials : creds , } ) ) lambdaService := lambda . New ( tempSession ) payload , err := json . Marshal ( SSHrimpEvent { PublicKey : string ( ssh . MarshalAuthorizedKey ( publicKey ) ) , Token : token , ForceCommand : forceCommand , } ) if err != nil { return nil , err } result , err := lambdaService . Invoke ( & lambda . InvokeInput { FunctionName : aws . String ( c . CertificateAuthority . FunctionName ) , Payload : payload , } ) if err != nil { return nil , err } if * result . StatusCode != 200 { return nil , fmt . Errorf ( " " , * result . StatusCode ) } sshrimpResult := SSHrimpResult { } err = json . Unmarshal ( result . Payload , & sshrimpResult ) if err != nil { return nil , errors . Wrap ( err , " " ) } if sshrimpResult . ErrorType != " " || sshrimpResult . ErrorMessage != " " { return nil , fmt . Errorf ( " " , sshrimpResult . ErrorType , sshrimpResult . ErrorMessage ) } cert , _ , _ , _ , err := ssh . ParseAuthorizedKey ( [ ] byte ( sshrimpResult . Certificate ) ) if err != nil { return nil , err } return cert . ( * ssh . Certificate ) , nil }
SignCertificateOneRegion given a public key, identity token and forceCommand, invoke the sshrimp-ca lambda function
SignCertificateOneRegion given a public key identity token and forceCommand invoke the sshrimp - ca lambda function
// Create a lambdaService using the new temporary credentials for the role // session := session.Must(session.NewSession()) <-- this is the other method for authenticating to AWS // Create a lambdaService using AssumeRoleWithWebIdentity <-- this shares the same Identity Provider as AWSs IAM // Create a STS client from just a session. // build the roleARN string for sending // extract the usernameClaim from the OIDC JWT // send these credentials to AWS to recieve temporary static credentials // use new temporary credentials for creating lambda service // Setup the JSON payload for the SSHrimp CA // Invoke the SSHrimp lambda // Parse the result form the lambda to extract the certificate // These error types and messages can also come from the aws-sdk-go lambda handler // Parse the certificate received by sshrimp-ca