The current code base of PyCrypto contains some code you may find interesting:
One open pull request (link) validates RSA and DSA as they are constructed. The tests are more robust than what you show above, even though a malicious user may still craft a weak key and have it pass them. For DSA keys, it goes like this:
# Modulus must be prime fmt_error = not isPrime(key.p) # Verify Lagrange's theorem for sub-group fmt_error |= ((key.p-1) % key.q)!=0 fmt_error |= key.g<=1 or key.g>=key.p fmt_error |= pow(key.g, key.q, key.p)!=1 # Public key fmt_error |= key.y<=0 or key.y>=key.p if hasattr(key, 'x'): fmt_error |= key.x<=0 or key.x>=key.q fmt_error |= pow(key.g, key.x, key.p)!=key.y
The main branch (see lib/Crypto/PublicKey/DSA.py) has code to import DSA keys in SSH format:
if extern_key.startswith(b('ssh-dss ')): # This is probably a public OpenSSH key keystring = binascii.a2b_base64(extern_key.split(b(' '))[1]) keyparts = [] while len(keystring) > 4: length = struct.unpack(">I", keystring[:4])[0] keyparts.append(keystring[4:4 + length]) keystring = keystring[4 + length:] if keyparts[0] == b("ssh-dss"): tup = [bytes_to_long(keyparts[x]) for x in (4, 3, 1, 2)] return self.construct(tup)