kopia lustrzana https://github.com/solokeys/solo1
				
				
				
			
							rodzic
							
								
									fc8bc892c1
								
							
						
					
					
						commit
						feceeb0a22
					
				
							
								
								
									
										60
									
								
								fido2/ctap.c
								
								
								
								
							
							
						
						
									
										60
									
								
								fido2/ctap.c
								
								
								
								
							|  | @ -302,10 +302,10 @@ static uint32_t auth_data_update_count(CTAP_authDataHeader * authData) | ||||||
|     } |     } | ||||||
|     uint8_t * byte = (uint8_t*) &authData->signCount; |     uint8_t * byte = (uint8_t*) &authData->signCount; | ||||||
| 
 | 
 | ||||||
|     *byte++ = (count >> 0) & 0xff; |  | ||||||
|     *byte++ = (count >> 8) & 0xff; |  | ||||||
|     *byte++ = (count >> 16) & 0xff; |  | ||||||
|     *byte++ = (count >> 24) & 0xff; |     *byte++ = (count >> 24) & 0xff; | ||||||
|  |     *byte++ = (count >> 16) & 0xff; | ||||||
|  |     *byte++ = (count >> 8) & 0xff; | ||||||
|  |     *byte++ = (count >> 0) & 0xff; | ||||||
| 
 | 
 | ||||||
|     return count; |     return count; | ||||||
| } | } | ||||||
|  | @ -344,6 +344,9 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au | ||||||
|     crypto_sha256_update(rp->id, rp->size); |     crypto_sha256_update(rp->id, rp->size); | ||||||
|     crypto_sha256_final(authData->head.rpIdHash); |     crypto_sha256_final(authData->head.rpIdHash); | ||||||
| 
 | 
 | ||||||
|  |     printf1(TAG_RED, "rpId: "); dump_hex1(TAG_RED, rp->id, rp->size); | ||||||
|  |     printf1(TAG_RED, "hash: "); dump_hex1(TAG_RED, authData->head.rpIdHash, 32); | ||||||
|  | 
 | ||||||
|     count = auth_data_update_count(&authData->head); |     count = auth_data_update_count(&authData->head); | ||||||
| 
 | 
 | ||||||
|     device_set_status(CTAPHID_STATUS_UPNEEDED); |     device_set_status(CTAPHID_STATUS_UPNEEDED); | ||||||
|  | @ -691,10 +694,10 @@ uint8_t ctap_add_user_entity(CborEncoder * map, CTAP_userEntity * user) | ||||||
|     int ret = cbor_encode_int(map, RESP_publicKeyCredentialUserEntity); |     int ret = cbor_encode_int(map, RESP_publicKeyCredentialUserEntity); | ||||||
|     check_ret(ret); |     check_ret(ret); | ||||||
| 
 | 
 | ||||||
|     int dispname = (user->name[0] != 0); |     int dispname = (user->name[0] != 0) && getAssertionState.user_verified; | ||||||
| 
 | 
 | ||||||
|     if (dispname) |     if (dispname) | ||||||
|         ret = cbor_encoder_create_map(map, &entity, 2); |         ret = cbor_encoder_create_map(map, &entity, 4); | ||||||
|     else |     else | ||||||
|         ret = cbor_encoder_create_map(map, &entity, 1); |         ret = cbor_encoder_create_map(map, &entity, 1); | ||||||
|     check_ret(ret); |     check_ret(ret); | ||||||
|  | @ -715,6 +718,20 @@ uint8_t ctap_add_user_entity(CborEncoder * map, CTAP_userEntity * user) | ||||||
| 
 | 
 | ||||||
|         ret = cbor_encode_text_stringz(&entity, (const char *)user->name); |         ret = cbor_encode_text_stringz(&entity, (const char *)user->name); | ||||||
|         check_ret(ret); |         check_ret(ret); | ||||||
|  | 
 | ||||||
|  |         ret = cbor_encode_text_string(&entity, "displayName", 11); | ||||||
|  |         check_ret(ret); | ||||||
|  | 
 | ||||||
|  |         ret = cbor_encode_text_stringz(&entity, (const char *)user->displayName); | ||||||
|  |         check_ret(ret); | ||||||
|  | 
 | ||||||
|  |         ret = cbor_encode_text_string(&entity, "icon", 4); | ||||||
|  |         check_ret(ret); | ||||||
|  | 
 | ||||||
|  |         ret = cbor_encode_text_stringz(&entity, (const char *)user->icon); | ||||||
|  |         check_ret(ret); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ret = cbor_encoder_close_container(map, &entity); |     ret = cbor_encoder_close_container(map, &entity); | ||||||
|  | @ -871,7 +888,9 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder) | ||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
|     CborEncoder map; |     CborEncoder map; | ||||||
|     CTAP_authDataHeader * authData = &getAssertionState.authData; |     CTAP_authDataHeader authData; | ||||||
|  |     memmove(&authData, &getAssertionState.authData, sizeof(CTAP_authDataHeader)); | ||||||
|  |     // CTAP_authDataHeader * authData = &getAssertionState.authData;
 | ||||||
| 
 | 
 | ||||||
|     CTAP_credentialDescriptor * cred = pop_credential(); |     CTAP_credentialDescriptor * cred = pop_credential(); | ||||||
| 
 | 
 | ||||||
|  | @ -880,10 +899,10 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder) | ||||||
|         return CTAP2_ERR_NOT_ALLOWED; |         return CTAP2_ERR_NOT_ALLOWED; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auth_data_update_count(authData); |     auth_data_update_count(&authData); | ||||||
|     int add_user_info = cred->credential.user.id_size && getAssertionState.user_verified; |     int add_user_info = cred->credential.user.id_size; | ||||||
| 
 | 
 | ||||||
|     if (getAssertionState.user_verified) |     if (add_user_info) | ||||||
|     { |     { | ||||||
|         printf1(TAG_GREEN, "adding user info to assertion response\r\n"); |         printf1(TAG_GREEN, "adding user info to assertion response\r\n"); | ||||||
|         ret = cbor_encoder_create_map(encoder, &map, 4); |         ret = cbor_encoder_create_map(encoder, &map, 4); | ||||||
|  | @ -895,15 +914,24 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     check_ret(ret); |     check_ret(ret); | ||||||
|  |     printf1(TAG_RED, "RPID hash: "); dump_hex1(TAG_RED, authData.rpIdHash, 32); | ||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
|         ret = cbor_encode_int(&map,RESP_authData); |         ret = cbor_encode_int(&map,RESP_authData); | ||||||
|         check_ret(ret); |         check_ret(ret); | ||||||
|         ret = cbor_encode_byte_string(&map, (uint8_t *)authData, sizeof(CTAP_authDataHeader)); |         ret = cbor_encode_byte_string(&map, (uint8_t *)&authData, sizeof(CTAP_authDataHeader)); | ||||||
|         check_ret(ret); |         check_ret(ret); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ret = ctap_end_get_assertion(&map, cred, (uint8_t *)authData, getAssertionState.clientDataHash, add_user_info); |     // if only one account for this RP, null out the user details
 | ||||||
|  |     if (!getAssertionState.user_verified) | ||||||
|  |     { | ||||||
|  |         printf1(TAG_GREEN, "Not verified, nulling out user details on response\r\n"); | ||||||
|  |         memset(cred->credential.user.name, 0, USER_NAME_LIMIT); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     ret = ctap_end_get_assertion(&map, cred, (uint8_t *)&authData, getAssertionState.clientDataHash, add_user_info); | ||||||
|     check_retr(ret); |     check_retr(ret); | ||||||
| 
 | 
 | ||||||
|     ret = cbor_encoder_close_container(encoder, &map); |     ret = cbor_encoder_close_container(encoder, &map); | ||||||
|  | @ -950,7 +978,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) | ||||||
|     printf1(TAG_GA, "ALLOW_LIST has %d creds\n", GA.credLen); |     printf1(TAG_GA, "ALLOW_LIST has %d creds\n", GA.credLen); | ||||||
|     int validCredCount = ctap_filter_invalid_credentials(&GA); |     int validCredCount = ctap_filter_invalid_credentials(&GA); | ||||||
| 
 | 
 | ||||||
|     int add_user_info = GA.creds[validCredCount - 1].credential.user.id_size && getAssertionState.user_verified; |     int add_user_info = GA.creds[validCredCount - 1].credential.user.id_size; | ||||||
|     if (validCredCount > 1) |     if (validCredCount > 1) | ||||||
|     { |     { | ||||||
|        map_size += 1; |        map_size += 1; | ||||||
|  | @ -995,7 +1023,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // if only one account for this RP, null out the user details
 |     // if only one account for this RP, null out the user details
 | ||||||
|     if (validCredCount < 2) |     if (validCredCount < 2 || !getAssertionState.user_verified) | ||||||
|     { |     { | ||||||
|         printf1(TAG_GREEN, "Only one account, nulling out user details on response\r\n"); |         printf1(TAG_GREEN, "Only one account, nulling out user details on response\r\n"); | ||||||
|         memset(&GA.creds[0].credential.user.name, 0, USER_NAME_LIMIT); |         memset(&GA.creds[0].credential.user.name, 0, USER_NAME_LIMIT); | ||||||
|  | @ -1340,11 +1368,13 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) | ||||||
|     length--; |     length--; | ||||||
| 
 | 
 | ||||||
|     uint8_t * buf = resp->data; |     uint8_t * buf = resp->data; | ||||||
|  |     printf1(TAG_GREEN, "lastcmd0 = 0x%02x\r\n", getAssertionState.lastcmd); | ||||||
| 
 | 
 | ||||||
|     cbor_encoder_init(&encoder, buf, resp->data_size, 0); |     cbor_encoder_init(&encoder, buf, resp->data_size, 0); | ||||||
| 
 | 
 | ||||||
|     printf1(TAG_CTAP,"cbor input structure: %d bytes\n", length); |     printf1(TAG_CTAP,"cbor input structure: %d bytes\n", length); | ||||||
|     printf1(TAG_DUMP,"cbor req: "); dump_hex1(TAG_DUMP, pkt_raw, length); |     printf1(TAG_DUMP,"cbor req: "); dump_hex1(TAG_DUMP, pkt_raw, length); | ||||||
|  |     printf1(TAG_GREEN, "lastcmd1 = 0x%02x\r\n", getAssertionState.lastcmd); | ||||||
| 
 | 
 | ||||||
|     switch(cmd) |     switch(cmd) | ||||||
|     { |     { | ||||||
|  | @ -1434,7 +1464,8 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 printf2(TAG_ERR, "unwanted GET_NEXT_ASSERTION\n"); |                 printf2(TAG_ERR, "unwanted GET_NEXT_ASSERTION.  lastcmd == 0x%02x\n", getAssertionState.lastcmd); | ||||||
|  |                 dump_hex1(TAG_GREEN, &getAssertionState, sizeof(getAssertionState)); | ||||||
|                 status = CTAP2_ERR_NOT_ALLOWED; |                 status = CTAP2_ERR_NOT_ALLOWED; | ||||||
|             } |             } | ||||||
|             break; |             break; | ||||||
|  | @ -1446,6 +1477,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) | ||||||
| done: | done: | ||||||
|     device_set_status(CTAPHID_STATUS_IDLE); |     device_set_status(CTAPHID_STATUS_IDLE); | ||||||
|     getAssertionState.lastcmd = cmd; |     getAssertionState.lastcmd = cmd; | ||||||
|  |     printf1(TAG_GREEN, "lastcmd = 0x%02x\r\n", getAssertionState.lastcmd); | ||||||
| 
 | 
 | ||||||
|     if (status != CTAP1_ERR_SUCCESS) |     if (status != CTAP1_ERR_SUCCESS) | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -109,6 +109,8 @@ | ||||||
| #define RP_NAME_LIMIT               32  // application limit, name parameter isn't needed.
 | #define RP_NAME_LIMIT               32  // application limit, name parameter isn't needed.
 | ||||||
| #define USER_ID_MAX_SIZE            64 | #define USER_ID_MAX_SIZE            64 | ||||||
| #define USER_NAME_LIMIT             65  // Must be minimum of 64 bytes but can be more.
 | #define USER_NAME_LIMIT             65  // Must be minimum of 64 bytes but can be more.
 | ||||||
|  | #define DISPLAY_NAME_LIMIT          32  // Must be minimum of 64 bytes but can be more.
 | ||||||
|  | #define ICON_LIMIT                  128 // Must be minimum of 64 bytes but can be more.
 | ||||||
| #define CTAP_MAX_MESSAGE_SIZE       1200 | #define CTAP_MAX_MESSAGE_SIZE       1200 | ||||||
| 
 | 
 | ||||||
| #define CREDENTIAL_RK_FLASH_PAD     2   // size of RK should be 8-byte aligned to store in flash easily.
 | #define CREDENTIAL_RK_FLASH_PAD     2   // size of RK should be 8-byte aligned to store in flash easily.
 | ||||||
|  | @ -140,6 +142,8 @@ typedef struct | ||||||
|     uint8_t id[USER_ID_MAX_SIZE]; |     uint8_t id[USER_ID_MAX_SIZE]; | ||||||
|     uint8_t id_size; |     uint8_t id_size; | ||||||
|     uint8_t name[USER_NAME_LIMIT]; |     uint8_t name[USER_NAME_LIMIT]; | ||||||
|  |     uint8_t displayName[DISPLAY_NAME_LIMIT]; | ||||||
|  |     uint8_t icon[ICON_LIMIT]; | ||||||
| }__attribute__((packed)) CTAP_userEntity; | }__attribute__((packed)) CTAP_userEntity; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|  |  | ||||||
|  | @ -175,6 +175,13 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val) | ||||||
|                 printf2(TAG_ERR,"Error, expecting text string type for user.displayName value\n"); |                 printf2(TAG_ERR,"Error, expecting text string type for user.displayName value\n"); | ||||||
|                 return CTAP2_ERR_INVALID_CBOR_TYPE; |                 return CTAP2_ERR_INVALID_CBOR_TYPE; | ||||||
|             } |             } | ||||||
|  |             sz = DISPLAY_NAME_LIMIT; | ||||||
|  |             ret = cbor_value_copy_text_string(&map, (char *)MC->user.displayName, &sz, NULL); | ||||||
|  |             if (ret != CborErrorOutOfMemory) | ||||||
|  |             {   // Just truncate the name it's okay
 | ||||||
|  |                 check_ret(ret); | ||||||
|  |             } | ||||||
|  |             MC->user.displayName[DISPLAY_NAME_LIMIT - 1] = 0; | ||||||
|         } |         } | ||||||
|         else if (strcmp((const char *)key, "icon") == 0) |         else if (strcmp((const char *)key, "icon") == 0) | ||||||
|         { |         { | ||||||
|  | @ -183,6 +190,14 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val) | ||||||
|                 printf2(TAG_ERR,"Error, expecting text string type for user.icon value\n"); |                 printf2(TAG_ERR,"Error, expecting text string type for user.icon value\n"); | ||||||
|                 return CTAP2_ERR_INVALID_CBOR_TYPE; |                 return CTAP2_ERR_INVALID_CBOR_TYPE; | ||||||
|             } |             } | ||||||
|  |             sz = ICON_LIMIT; | ||||||
|  |             ret = cbor_value_copy_text_string(&map, (char *)MC->user.icon, &sz, NULL); | ||||||
|  |             if (ret != CborErrorOutOfMemory) | ||||||
|  |             {   // Just truncate the name it's okay
 | ||||||
|  |                 check_ret(ret); | ||||||
|  |             } | ||||||
|  |             MC->user.icon[ICON_LIMIT - 1] = 0; | ||||||
|  | 
 | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|  |  | ||||||
|  | @ -97,7 +97,7 @@ void ctaphid_init() | ||||||
| { | { | ||||||
|     state = IDLE; |     state = IDLE; | ||||||
|     buffer_reset(); |     buffer_reset(); | ||||||
|     ctap_reset_state(); |     //ctap_reset_state();
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t get_new_cid() | static uint32_t get_new_cid() | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #define DEBUG_UART      USART1 | #define DEBUG_UART      USART1 | ||||||
| 
 | 
 | ||||||
| #define DEBUG_LEVEL        1 | #define DEBUG_LEVEL        0 | ||||||
| 
 | 
 | ||||||
| #define NON_BLOCK_PRINTING 0 | #define NON_BLOCK_PRINTING 0 | ||||||
| 
 | 
 | ||||||
|  | @ -33,7 +33,7 @@ void hw_init(void); | ||||||
| #define SOLO_BUTTON_PORT        GPIOA | #define SOLO_BUTTON_PORT        GPIOA | ||||||
| #define SOLO_BUTTON_PIN         LL_GPIO_PIN_0 | #define SOLO_BUTTON_PIN         LL_GPIO_PIN_0 | ||||||
| 
 | 
 | ||||||
| #define SKIP_BUTTON_CHECK_WITH_DELAY        1 | #define SKIP_BUTTON_CHECK_WITH_DELAY        0 | ||||||
| #define SKIP_BUTTON_CHECK_FAST              0 | #define SKIP_BUTTON_CHECK_FAST              0 | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -390,7 +390,7 @@ class Tester(): | ||||||
|     def test_fido2_simple(self, pin_token=None): |     def test_fido2_simple(self, pin_token=None): | ||||||
|         creds = [] |         creds = [] | ||||||
|         exclude_list = [] |         exclude_list = [] | ||||||
|         rp = {'id': 'examplo.org', 'name': 'ExaRP'} |         rp = {'id': self.origin, 'name': 'ExaRP'} | ||||||
|         user = {'id': b'usee_od', 'name': 'AB User'} |         user = {'id': b'usee_od', 'name': 'AB User'} | ||||||
|         challenge = 'Y2hhbGxlbmdl' |         challenge = 'Y2hhbGxlbmdl' | ||||||
|         PIN = pin_token |         PIN = pin_token | ||||||
|  | @ -432,7 +432,6 @@ class Tester(): | ||||||
|         for i in range(0,2048**2): |         for i in range(0,2048**2): | ||||||
|             creds = [] |             creds = [] | ||||||
| 
 | 
 | ||||||
|             print(i) |  | ||||||
|             challenge = ''.join([abc[randint(0,len(abc)-1)] for x in range(0,32)]) |             challenge = ''.join([abc[randint(0,len(abc)-1)] for x in range(0,32)]) | ||||||
| 
 | 
 | ||||||
|             fake_id1 = array.array('B',[randint(0,255) for i in range(0,150)]).tostring() |             fake_id1 = array.array('B',[randint(0,255) for i in range(0,150)]).tostring() | ||||||
|  | @ -445,6 +444,7 @@ class Tester(): | ||||||
|             for i in range(0,1): |             for i in range(0,1): | ||||||
|                 t1 = time.time() * 1000 |                 t1 = time.time() * 1000 | ||||||
|                 attest, data = self.client.make_credential(rp, user, challenge, pin = PIN, exclude_list = []) |                 attest, data = self.client.make_credential(rp, user, challenge, pin = PIN, exclude_list = []) | ||||||
|  |                 print(attest.auth_data.counter) | ||||||
|                 t2 = time.time() * 1000 |                 t2 = time.time() * 1000 | ||||||
|                 attest.verify(data.hash) |                 attest.verify(data.hash) | ||||||
|                 print('Register valid (%d ms)' % (t2-t1)) |                 print('Register valid (%d ms)' % (t2-t1)) | ||||||
|  | @ -460,6 +460,7 @@ class Tester(): | ||||||
|                 assertions, client_data = self.client.get_assertion(rp['id'], challenge, allow_list, pin = PIN) |                 assertions, client_data = self.client.get_assertion(rp['id'], challenge, allow_list, pin = PIN) | ||||||
|                 t2 = time.time() * 1000 |                 t2 = time.time() * 1000 | ||||||
|                 assertions[0].verify(client_data.hash, creds[0].public_key) |                 assertions[0].verify(client_data.hash, creds[0].public_key) | ||||||
|  |                 print(assertions[0].auth_data.counter) | ||||||
| 
 | 
 | ||||||
|                 print('Assertion valid (%d ms)' % (t2-t1)) |                 print('Assertion valid (%d ms)' % (t2-t1)) | ||||||
|                 sys.stdout.flush() |                 sys.stdout.flush() | ||||||
|  | @ -607,6 +608,160 @@ class Tester(): | ||||||
|             print('Warning, reset failed: ', e) |             print('Warning, reset failed: ', e) | ||||||
|         print('PASS') |         print('PASS') | ||||||
| 
 | 
 | ||||||
|  |     def test_rk(self, ): | ||||||
|  |         creds = [] | ||||||
|  |         rp = {'id': 'examplo.org', 'name': 'ExaRP'} | ||||||
|  |         user0 = {'id': b'first one', 'name': 'single User'} | ||||||
|  | 
 | ||||||
|  |         users = [{'id': b'user' + os.urandom(16), 'name': 'AB User'} for i in range(0,2)] | ||||||
|  |         challenge = 'Y2hhbGxlbmdl' | ||||||
|  |         PIN = None | ||||||
|  |         print('reset') | ||||||
|  |         self.ctap.reset() | ||||||
|  |         #if PIN: self.client.pin_protocol.set_pin(PIN) | ||||||
|  | 
 | ||||||
|  |         print('registering 1 user with RK') | ||||||
|  |         t1 = time.time() * 1000 | ||||||
|  |         attest, data = self.client.make_credential(rp, user0, challenge, pin = PIN, exclude_list = [], rk = True) | ||||||
|  |         t2 = time.time() * 1000 | ||||||
|  |         attest.verify(data.hash) | ||||||
|  |         creds.append(attest.auth_data.credential_data) | ||||||
|  |         print('Register valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  |         print('1 assertion') | ||||||
|  |         t1 = time.time() * 1000 | ||||||
|  |         assertions, client_data = self.client.get_assertion(rp['id'], challenge, pin = PIN) | ||||||
|  |         t2 = time.time() * 1000 | ||||||
|  |         assertions[0].verify(client_data.hash, creds[0].public_key) | ||||||
|  |         print('Assertion valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  |         print(assertions[0], client_data) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         print('registering %d users with RK' % len(users)) | ||||||
|  |         for i in range(0,len(users)): | ||||||
|  |             t1 = time.time() * 1000 | ||||||
|  |             attest, data = self.client.make_credential(rp, users[i], challenge, pin = PIN, exclude_list = [], rk = True) | ||||||
|  |             t2 = time.time() * 1000 | ||||||
|  |             attest.verify(data.hash) | ||||||
|  |             print('Register valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  |             creds.append(attest.auth_data.credential_data) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         t1 = time.time() * 1000 | ||||||
|  |         assertions, client_data = self.client.get_assertion(rp['id'], challenge, pin = PIN) | ||||||
|  |         t2 = time.time() * 1000 | ||||||
|  | 
 | ||||||
|  |         for x,y in zip(assertions, creds): | ||||||
|  |             x.verify(client_data.hash,y.public_key) | ||||||
|  | 
 | ||||||
|  |         print('Assertion(s) valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         print('registering a duplicate user ') | ||||||
|  | 
 | ||||||
|  |         t1 = time.time() * 1000 | ||||||
|  |         attest, data = self.client.make_credential(rp, users[1], challenge, pin = PIN, exclude_list = [], rk = True) | ||||||
|  |         t2 = time.time() * 1000 | ||||||
|  |         attest.verify(data.hash) | ||||||
|  |         creds = creds[:2] + creds[3:]  + [attest.auth_data.credential_data] | ||||||
|  |         print('Register valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         t1 = time.time() * 1000 | ||||||
|  |         assertions, client_data = self.client.get_assertion(rp['id'], challenge, pin = PIN) | ||||||
|  |         t2 = time.time() * 1000 | ||||||
|  |         assert(len(assertions) == len(users) +1) | ||||||
|  |         for x,y in zip(assertions, creds): | ||||||
|  |             x.verify(client_data.hash,y.public_key) | ||||||
|  | 
 | ||||||
|  |         print('Assertion(s) valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def test_responses(self,): | ||||||
|  |         PIN = '1234' | ||||||
|  |         RPID = 'examplo2.org' | ||||||
|  |         for dev in (CtapHidDevice.list_devices()): | ||||||
|  |             print('dev',dev) | ||||||
|  |             client = Fido2Client(dev, RPID) | ||||||
|  |             ctap = client.ctap2 | ||||||
|  |             # ctap.reset() | ||||||
|  |             try: | ||||||
|  |                 if PIN: client.pin_protocol.set_pin(PIN) | ||||||
|  |             except:pass | ||||||
|  | 
 | ||||||
|  |             inf = ctap.get_info() | ||||||
|  |             #print (inf) | ||||||
|  |             print('versions: ',inf.versions) | ||||||
|  |             print('aaguid: ',inf.aaguid) | ||||||
|  |             print('rk: ',inf.options['rk']) | ||||||
|  |             print('clientPin: ',inf.options['clientPin']) | ||||||
|  |             print('max_message_size: ',inf.max_msg_size) | ||||||
|  | 
 | ||||||
|  |             #rp = {'id': 'SelectDevice', 'name': 'SelectDevice'} | ||||||
|  |             rp = {'id': RPID, 'name': 'ExaRP'} | ||||||
|  |             user = {'id': os.urandom(10), 'name': 'SelectDevice'} | ||||||
|  |             user = {'id': b'21first one', 'name': 'single User'} | ||||||
|  |             challenge = 'Y2hhbGxlbmdl' | ||||||
|  | 
 | ||||||
|  |             if 1: | ||||||
|  |                 attest, data = client.make_credential(rp, | ||||||
|  |                         user, challenge, exclude_list = [], pin = PIN, rk=True) | ||||||
|  | 
 | ||||||
|  |                 cred = attest.auth_data.credential_data | ||||||
|  |                 creds = [cred] | ||||||
|  | 
 | ||||||
|  |                 allow_list = [{'id':creds[0].credential_id, 'type': 'public-key'}] | ||||||
|  |                 allow_list = [] | ||||||
|  |                 assertions, client_data = client.get_assertion(rp['id'], challenge, pin = PIN) | ||||||
|  |                 assertions[0].verify(client_data.hash, creds[0].public_key) | ||||||
|  | 
 | ||||||
|  |             if 0: | ||||||
|  |                 print('registering 1 user with RK') | ||||||
|  |                 t1 = time.time() * 1000 | ||||||
|  |                 attest, data = client.make_credential(rp, user, challenge, pin = PIN, exclude_list = [], rk = True) | ||||||
|  |                 t2 = time.time() * 1000 | ||||||
|  |                 attest.verify(data.hash) | ||||||
|  |                 creds = [attest.auth_data.credential_data] | ||||||
|  |                 print('Register valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  |                 print('1 assertion') | ||||||
|  |                 t1 = time.time() * 1000 | ||||||
|  |                 assertions, client_data = client.get_assertion(rp['id'], challenge, pin = PIN) | ||||||
|  |                 t2 = time.time() * 1000 | ||||||
|  |                 assertions[0].verify(client_data.hash, creds[0].public_key) | ||||||
|  |                 print('Assertion valid (%d ms)' % (t2-t1)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             #print('fmt:',attest.fmt) | ||||||
|  |             #print('rp_id_hash',attest.auth_data.rp_id_hash) | ||||||
|  |             #print('flags:', hex(attest.auth_data.flags)) | ||||||
|  |             #print('count:', hex(attest.auth_data.counter)) | ||||||
|  |             print('flags MC:',attest.auth_data) | ||||||
|  |             print('flags GA:',assertions[0].auth_data) | ||||||
|  |             #print('cred_id:',attest.auth_data.credential_data.credential_id) | ||||||
|  |             #print('pubkey:',attest.auth_data.credential_data.public_key) | ||||||
|  |             #print('aaguid:',attest.auth_data.credential_data.aaguid) | ||||||
|  |             # print('cred data:',attest.auth_data.credential_data) | ||||||
|  |             # print('auth_data:',attest.auth_data) | ||||||
|  |             #print('auth_data:',attest.auth_data) | ||||||
|  |             #print('alg:',attest.att_statement['alg']) | ||||||
|  |             #print('sig:',attest.att_statement['sig']) | ||||||
|  |             #print('x5c:',attest.att_statement['x5c']) | ||||||
|  |             #print('data:',data) | ||||||
|  | 
 | ||||||
|  |             print('assertion:', assertions[0]) | ||||||
|  |             print('clientData:', client_data) | ||||||
|  | 
 | ||||||
|  |             print() | ||||||
|  |             #break | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def test_find_brute_force(): | def test_find_brute_force(): | ||||||
|     i = 0 |     i = 0 | ||||||
|     while 1: |     while 1: | ||||||
|  | @ -621,10 +776,12 @@ def test_find_brute_force(): | ||||||
| 
 | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|     t = Tester() |     t = Tester() | ||||||
|     t.find_device() |     #t.find_device() | ||||||
|     # t.test_hid() |     # t.test_hid() | ||||||
|     # t.test_long_ping() |     # t.test_long_ping() | ||||||
|     t.test_fido2() |     #t.test_fido2() | ||||||
|  |     #t.test_rk() | ||||||
|  |     t.test_responses() | ||||||
|     # test_find_brute_force() |     # test_find_brute_force() | ||||||
|     #t.test_fido2_simple() |     #t.test_fido2_simple() | ||||||
|     #t.test_fido2_brute_force() |     #t.test_fido2_brute_force() | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Conor Patrick
						Conor Patrick