Line 6: |
Line 6: |
| | | |
| Problem is which bit of the certificates is e and which is n? | | Problem is which bit of the certificates is e and which is n? |
| + | |
| + | == sample code per request == |
| + | |
| + | Here's a Snippet of how I walk the keys and check everything I possibly can. The presumption is you already have the binary blob of the cert section (u8 *c), and the reported length of the cert from the header (w_hdr.sz_crt): |
| + | |
| + | #define round_up(x,n)(-(-(x)&-(n))) |
| + | typedef unsigned char u8; |
| + | typedef unsigned short u16; |
| + | typedef unsigned int u32; |
| + | struct wad_crt{ |
| + | u32 sig_type; |
| + | u8 sig[0x200]; |
| + | u8 fill1[0x3C]; |
| + | u8 issuer[0x40]; |
| + | u32 key_type; |
| + | u8 child[0x40]; |
| + | u8 pub_key[0x204]; |
| + | u8 fill2[0x38]; |
| + | }; |
| + | |
| + | static u8 num_crt; |
| + | |
| + | static void get_crt(u8 *c){ |
| + | u64 j=0; |
| + | u16 i,s,k; |
| + | struct wad_crt * tmp=NULL; |
| + | for(num_crt=0;;num_crt++){ |
| + | if(sizeof w_crt!=(num_crt+1)*sizeof(struct wad_crt)){ |
| + | tmp=(struct wad_crt *)realloc(w_crt,(num_crt+1)*sizeof(struct wad_crt)); |
| + | if(tmp!=NULL) w_crt=tmp; |
| + | } |
| + | w_crt[num_crt].sig_type=be32(c+j); |
| + | switch(w_crt[num_crt].sig_type){ |
| + | case 0x00010000: s=0x200; break; /*RSA_4096*/ |
| + | case 0x00010001: s=0x100; break; /*RSA_2048*/ |
| + | case 0x00010002: s=0x40; break; /*ECC*/ |
| + | default: |
| + | fprintf(stderr," get_crt[%u]: unknown sig_type (%08x)\n",num_crt,w_crt[num_crt].sig_type); |
| + | exit(1); |
| + | } |
| + | strncpy(w_crt[num_crt].sig, c+j+0x04, s); |
| + | strncpy(w_crt[num_crt].fill1, c+j+s+0x04, 0x3C); |
| + | strncpy(w_crt[num_crt].issuer, c+j+s+0x40, 0x40); |
| + | w_crt[num_crt].key_type=be32( c+j+s+0x80); |
| + | switch(w_crt[num_crt].key_type){ |
| + | case 0x00000000: k=0x204; break; /*RSA_4096*/ |
| + | case 0x00000001: k=0x104; break; /*RSA_2048*/ |
| + | default: |
| + | fprintf(stderr," get_crt[%u]: unknown key_type (%08x)\n",num_crt,w_crt[num_crt].key_type); |
| + | exit(1); |
| + | } |
| + | strncpy(w_crt[num_crt].child ,c+j+s+0x84, 0x40); |
| + | strncpy(w_crt[num_crt].pub_key,c+j+s+0xC4, k); |
| + | strncpy(w_crt[num_crt].fill2, c+j+s+k+0xC4,0x38); |
| + | |
| + | for(i=0;i<0x3c;i++){ |
| + | if(w_crt[num_crt].fill1[i]!=0x00){ |
| + | fprintf(stderr," get_crt[%u]: fill1 is non-zero padded\n",num_crt); |
| + | exit(1); |
| + | } |
| + | } |
| + | if(strncmp(w_crt[num_crt].issuer,"Root",4)!=0){ |
| + | fprintf(stderr," get_crt[%u]: unknown issuer (%s)\n",num_crt,w_crt[num_crt].issuer); |
| + | exit(1); |
| + | } |
| + | for(i=0;i<0x38;i++){ |
| + | if(w_crt[num_crt].fill2[i]!=0x00){ |
| + | fprintf(stderr," get_crt[%u]: fill2 is non-zero padded\n",num_crt); |
| + | exit(1); |
| + | } |
| + | } |
| + | j+=round_up(s+k+0xFC,0x40); |
| + | if(j >= round_up(w_hdr.sz_crt,0x40)) break; |
| + | } |
| + | } |