int check_padding_and_structure(out, length) { pad = out[length - 1]; if(pad > 16) return -1; // Bad padding byte n = length - pad; for(i = n; i < length; i++) // check padding if(out[i] != pad) return -1; /* match structure with known standard structure */ outfile = BIO_new(BIO_s_mem()); ASN1_parse(outfile, out, legnth, 0); BIO_gets(outfile, (char*)output, N); res = memem(output, 128, "SEQUENCE", 8); if (!res) goto bad; BIO_gets(outfile, (char*)output, N); res = memem(output, 128, ":00", 3); if (!res) goto bad; res = memem(output, 128, "INTEGER", 7); if (!res) goto bad; BIO_gets(outfile, (char*)output, N); res = memem(output, 128, "INTEGER", 7); if (!res) goto bad; /* now this integer has to be big, check minimum length */ ul = strlen((char*)res); p = res; while(*p) { if (isspace(*p)) ul--; p++; } if (ul < 32) goto bad; return 0; bad: return -1; }
static inline int check_padding_and_structure(unsigned char *out, int length) { int pad; int i; int n; unsigned char output[N]; int ul; /* useful length */ unsigned char *res = NULL; unsigned char *p; BIO * outfile; // First check padding pad = out[length - 1]; if(pad > 16) return -1; n = length - pad; for(i = n; i < length; i++) if(out[i] != pad) return -1; /* check BER decoding, private key file contains: * RSAPrivateKey = { version = 0, n, e, d, p, q, d mod p-1, d mod q-1, q**-1 mod p } * DSAPrivateKey = { version = 0, p, q, g, y, x } */ memset(output, 0, N); outfile = BIO_new(BIO_s_mem()); ASN1_parse(outfile, out, cur_salt->ctl, 0); BIO_gets(outfile, (char*)output, N); res = memmem(output, 128, "SEQUENCE", 8); if (!res) { goto bad; } BIO_gets(outfile, (char*)output, N); res = memmem(output, 128, ":00", 3); if (!res) { goto bad; } res = memmem(output, 128, "INTEGER", 7); if (!res) { goto bad; } /* one more level of check */ BIO_gets(outfile, (char*)output, N); res = memmem(output, 128, "INTEGER", 7); if (!res) { goto bad; } /* NOTE: now this integer has to be big, is this always true? * RSA (as used in ssh) uses big prime numbers, so this check should be OK */ ul = strlen((char*)res); p = res; while(*p) { if (isspace(*p)) ul--; p++; } if (ul < 32) goto bad; BIO_free(outfile); return 0; bad: BIO_free(outfile); return -1; }