kopia lustrzana https://github.com/solokeys/solo1
				
				
				
			Handle empty pinAuth fields.
CTAP2 specifies that an empty pinAuth field is special: it indicates that the device should block for touch, i.e. it's just a way of letting a user select from multiple authenticators[1]. This change handles empty pinAuth fields in GetAssertion and MakeCredential commands. [1] https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#using-pinToken-in-authenticatorMakeCredentialpull/179/head
							rodzic
							
								
									f28cf9c6d0
								
							
						
					
					
						commit
						a5f794c0ff
					
				
							
								
								
									
										16
									
								
								fido2/ctap.c
								
								
								
								
							
							
						
						
									
										16
									
								
								fido2/ctap.c
								
								
								
								
							|  | @ -702,6 +702,14 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt | |||
|         printf2(TAG_ERR,"error, parse_make_credential failed\n"); | ||||
|         return ret; | ||||
|     } | ||||
|     if (MC.pinAuthEmpty) | ||||
|     { | ||||
|         if (!device_is_nfc() && !ctap_user_presence_test()) | ||||
|         { | ||||
|                 return CTAP2_ERR_OPERATION_DENIED; | ||||
|         } | ||||
|         return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_INVALID : CTAP2_ERR_PIN_NOT_SET; | ||||
|     } | ||||
|     if ((MC.paramsParsed & MC_requiredMask) != MC_requiredMask) | ||||
|     { | ||||
|         printf2(TAG_ERR,"error, required parameter(s) for makeCredential are missing\n"); | ||||
|  | @ -1133,6 +1141,14 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) | |||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     if (GA.pinAuthEmpty) | ||||
|     { | ||||
|         if (!device_is_nfc() && !ctap_user_presence_test()) | ||||
|         { | ||||
|                 return CTAP2_ERR_OPERATION_DENIED; | ||||
|         } | ||||
|         return ctap_is_pin_set() == 1 ? CTAP2_ERR_PIN_INVALID : CTAP2_ERR_PIN_NOT_SET; | ||||
|     } | ||||
|     if (GA.pinAuthPresent) | ||||
|     { | ||||
|         ret = verify_pin_auth(GA.pinAuth, GA.clientDataHash); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								fido2/ctap.h
								
								
								
								
							
							
						
						
									
										10
									
								
								fido2/ctap.h
								
								
								
								
							|  | @ -243,6 +243,11 @@ typedef struct | |||
| 
 | ||||
|     uint8_t pinAuth[16]; | ||||
|     uint8_t pinAuthPresent; | ||||
|     // pinAuthEmpty is true iff an empty bytestring was provided as pinAuth.
 | ||||
|     // This is exclusive with |pinAuthPresent|. It exists because an empty
 | ||||
|     // pinAuth is a special signal to block for touch. See
 | ||||
|     // https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#using-pinToken-in-authenticatorMakeCredential
 | ||||
|     uint8_t pinAuthEmpty; | ||||
|     int pinProtocol; | ||||
|     CTAP_extensions extensions; | ||||
| 
 | ||||
|  | @ -266,6 +271,11 @@ typedef struct | |||
| 
 | ||||
|     uint8_t pinAuth[16]; | ||||
|     uint8_t pinAuthPresent; | ||||
|     // pinAuthEmpty is true iff an empty bytestring was provided as pinAuth.
 | ||||
|     // This is exclusive with |pinAuthPresent|. It exists because an empty
 | ||||
|     // pinAuth is a special signal to block for touch. See
 | ||||
|     // https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#using-pinToken-in-authenticatorGetAssertion
 | ||||
|     uint8_t pinAuthEmpty; | ||||
|     int pinProtocol; | ||||
| 
 | ||||
|     CTAP_credentialDescriptor creds[ALLOW_LIST_MAX_SIZE]; | ||||
|  |  | |||
|  | @ -823,14 +823,22 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod | |||
|                 ret = parse_options(&map, &MC->credInfo.rk, &MC->uv, &MC->up); | ||||
|                 check_retr(ret); | ||||
|                 break; | ||||
|             case MC_pinAuth: | ||||
|             case MC_pinAuth: { | ||||
|                 printf1(TAG_MC,"CTAP_pinAuth\n"); | ||||
| 
 | ||||
|                 size_t pinSize; | ||||
|                 if (cbor_value_get_type(&map) == CborByteStringType && | ||||
|                     cbor_value_get_string_length(&map, &pinSize) == CborNoError && | ||||
|                     pinSize == 0) | ||||
|                 { | ||||
|                     MC->pinAuthEmpty = 1; | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 ret = parse_fixed_byte_string(&map, MC->pinAuth, 16); | ||||
|                 if (CTAP1_ERR_INVALID_LENGTH != ret)    // damn microsoft
 | ||||
|                 { | ||||
|                     check_retr(ret); | ||||
| 
 | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|  | @ -838,6 +846,7 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod | |||
|                 } | ||||
|                 MC->pinAuthPresent = 1; | ||||
|                 break; | ||||
|             } | ||||
|             case MC_pinProtocol: | ||||
|                 printf1(TAG_MC,"CTAP_pinProtocol\n"); | ||||
|                 if (cbor_value_get_type(&map) == CborIntegerType) | ||||
|  | @ -1055,9 +1064,18 @@ uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int | |||
|                 ret = parse_options(&map, &GA->rk, &GA->uv, &GA->up); | ||||
|                 check_retr(ret); | ||||
|                 break; | ||||
|             case GA_pinAuth: | ||||
|             case GA_pinAuth: { | ||||
|                 printf1(TAG_GA,"CTAP_pinAuth\n"); | ||||
| 
 | ||||
|                 size_t pinSize; | ||||
|                 if (cbor_value_get_type(&map) == CborByteStringType && | ||||
|                     cbor_value_get_string_length(&map, &pinSize) == CborNoError && | ||||
|                     pinSize == 0) | ||||
|                 { | ||||
|                     GA->pinAuthEmpty = 1; | ||||
|                     break; | ||||
|                 } | ||||
| 
 | ||||
|                 ret = parse_fixed_byte_string(&map, GA->pinAuth, 16); | ||||
|                 if (CTAP1_ERR_INVALID_LENGTH != ret)    // damn microsoft
 | ||||
|                 { | ||||
|  | @ -1073,6 +1091,7 @@ uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int | |||
|                 GA->pinAuthPresent = 1; | ||||
| 
 | ||||
|                 break; | ||||
|             } | ||||
|             case GA_pinProtocol: | ||||
|                 printf1(TAG_GA,"CTAP_pinProtocol\n"); | ||||
|                 if (cbor_value_get_type(&map) == CborIntegerType) | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Adam Langley
						Adam Langley