def generateDescriptors(bridge=True, withoutTAP=False, withoutNTOR=False): """Create keys, certs, signatures, documents and descriptors for an OR. :param bool bridge: If ``True``, generate Bridge descriptors; otherwise, generate Relay descriptors. :param bool withoutTAP: If ``True``, generate descriptors without support for the TAP handshake, e.g. without RSA keys. :param bool withoutTAP: If ``True``, generate descriptors without support for the ntor handshake, e.g. without Ed25519 keys. :returns: A 3-tuple of strings: - a ``@type [bridge-]extra-info`` descriptor, - a ``@type [bridge-]server-descriptor``, and - a ``@type network-status`` document for a mock Tor relay/bridge. """ ipv4 = util.randomIPv4() ipv6 = util.randomIPv6() port = util.randomPort() nick = nicknames.generateNickname() vers = torversions.getRandomVersion() uptime = int(random.randint(1800, 63072000)) bandwidth = server.makeBandwidthLine() timestamp = util.makeTimeStamp(variation=True, period=36) protocols = server.makeProtocolsLine(vers) if withoutTAP: (secretOnionKey, publicOnionKey, onionKeyLine) = (None, None, None) else: (secretOnionKey, publicOnionKey, onionKeyLine) = crypto.generateOnionKey() (secretSigningKey, publicSigningKey, signingKeyLine) = crypto.generateSigningKey() secretNTORKey = None publicNTORKey = None if not withoutNTOR and nacl: try: secretNTORKey = ntor.createNTORSecretKey() publicNTORKey = ntor.getNTORPublicKey(secretNTORKey) except ntor.NTORKeyCreationError as error: secretNTORKey = None publicNTORKey = None (fingerprintSpacey, fingerprintBinary) = crypto.getFingerprint(publicSigningKey) fingerprintSmooshed = crypto.convertToSmooshedFingerprint(fingerprintSpacey) extrainfoDoc = extrainfo.generateExtraInfo(nick, fingerprintSmooshed, timestamp, ipv4, port, bridge=bridge) (extrainfoDigestBinary, extrainfoDigest, extrainfoDigestPKCS1) = crypto.digestDescriptorContent(extrainfoDoc) extrainfoDesc = crypto.signDescriptorContent(extrainfoDoc, secretSigningKey, digest=extrainfoDigestPKCS1) serverDoc = server.generateServerDescriptor(nick, fingerprintSpacey, timestamp, ipv4, ipv6, port, vers, protocols, uptime, bandwidth, extrainfoDigest, onionKeyLine, signingKeyLine, publicNTORKey, bridge=bridge) (serverDigestBinary, serverDigest, serverDigestPKCS1) = crypto.digestDescriptorContent(serverDoc) if bridge: serverDoc = b'@purpose bridge\n' + serverDoc serverDesc = crypto.signDescriptorContent(serverDoc, secretSigningKey, digest=serverDigestPKCS1) netstatusDesc = netstatus.generateBridgeNetstatus(nick, fingerprintBinary, serverDigestBinary, timestamp, ipv4, port, ipv6=ipv6, bandwidth_line=bandwidth) return (extrainfoDesc, serverDesc, netstatusDesc)
def generateDescriptors(): """Create keys, certs, signatures, documents and descriptors for an OR. :returns: A 3-tuple of strings: - a ``@type [bridge-]extra-info`` descriptor, - a ``@type [bridge-]server-descriptor``, and - a ``@type network-status`` document for a mock Tor relay/bridge. """ ipv4 = util.randomIPv4() ipv6 = util.randomIPv6() port = util.randomPort() nick = nicknames.generateNickname() vers = torversions.getRandomVersion() uptime = int(random.randint(1800, 63072000)) bandwidth = server.makeBandwidthLine() timestamp = util.makeTimeStamp(variation=True, period=36) protocols = server.makeProtocolsLine(vers) SIDSKey, SIDPCert, (onionkey, signingkey) = crypto.makeOnionKeys() idkeyPrivate = tls.getPrivateKey(SIDSKey) idkeyDigest = hashlib.sha1(idkeyPrivate).digest() idkeyPublic = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_ASN1, SIDPCert.get_pubkey()) idkeyPublic = re.sub(const.OPENSSL_BEGIN_KEY, '', idkeyPublic) idkeyPublic = re.sub(const.OPENSSL_END_KEY, '', idkeyPublic) idkeyPublic = idkeyPublic.strip() identDigest = hashlib.sha1(idkeyPublic).digest() fingerprint = hashlib.sha1(idkeyPublic).hexdigest().upper() fpr = crypto.convertToSpaceyFingerprint(fingerprint) extrainfoDoc = extrainfo.generateExtraInfo(nick, fingerprint, timestamp, ipv4, port) extrainfoDigest = hashlib.sha1(extrainfoDoc).digest() extrainfoHexdigest = hashlib.sha1(extrainfoDoc).hexdigest().upper() extrainfoSig = crypto.signDescriptorDigest(SIDSKey, extrainfoDigest) extrainfoDesc = extrainfoDoc + extrainfoSig serverDoc = [] serverDoc.append("@purpose bridge") serverDoc.append("router %s %s %s 0 0" % (nick, ipv4, port)) serverDoc.append("or-address [%s]:%s" % (ipv6, port)) serverDoc.append("platform Tor %s on Linux" % vers) serverDoc.append("%s\npublished %s" % (protocols, timestamp)) serverDoc.append("%s" % server.makeFingerprintLine(fingerprint, vers)) serverDoc.append("uptime %s\n%s" % (uptime, bandwidth)) serverDoc.append("%s" % server.makeExtraInfoDigestLine(extrainfoHexdigest, vers)) serverDoc.append("%s%s%s" % (onionkey, signingkey, server.makeHSDirLine(vers))) serverDoc.append("contact Somebody <*****@*****.**>") if nacl is not None: ntorkey = ntor.getNTORPublicKey() if ntorkey is not None: serverDoc.append("ntor-onion-key %s" % ntorkey) serverDoc.append("reject *:*\nrouter-signature\n") serverDesc = '\n'.join(serverDoc) serverDescDigest = hashlib.sha1(serverDesc).digest() netstatusDesc = netstatus.generateNetstatus(nick, identDigest, serverDescDigest, timestamp, ipv4, port, ipv6=ipv6, bandwidth_line=bandwidth) serverDesc += crypto.signDescriptorDigest(SIDSKey, serverDescDigest) return extrainfoDesc, serverDesc, netstatusDesc