PNRP is the acronym for peer-name resolution protocol, so it basically maps names to addresses, like dns, but using a peer to peer network to publish, resolve and store the records.
On Windows, pnrp is even mapped into the regular domain space using .pnrp.net as suffix, so test.pnrp.net would be resolved within the PNRP cloud on Windows.
Contrary to DNS, records in the PNRP cloud are free of charge and everybody is allowed to publish every record without providing any information like WHOIS.
For PNRP there are no subdomains, PNRP records consist of a Classifier and the Authority.
For test.pnrp.net, “test” is the Classifier and the Authority is “0”, the zero Authority makes this a unsecure PNRP record, everybody is able to publish the “test.pnrp.net” record.
PNRP knows another type of records, secure records.
For secure records, the Authority is the hexadecimal representation of the public RSA key of the Identity - we'll get into this later.
A secure record would look like “ptest-p.p428fed1c3a15ecad4b66ec96935dea8547d32fac.pnrp.net”, where “428fed1c3a15ecad4b66ec96935dea8547d32fac” is the Authority and “test” is the Classifier.
As PNRP records are case sensitive, and domains shall not start with a number, there are certain rules how to create PNRP records …
If the Authority starts with a number, it has to be prefixed with p, the zero Authority which would look like “p0” for “test.p0.pnrp.net” can be removed, resulting in “test.pnrp.net”.
If the Classifier contains uppercase characters or unicode chars, it has to be encoded using punycode. We'll stick to lowercase ascii Classifiers for this reason.
The official documentation on PNRP is pretty good, but I felt removing some details and adding some real world examples would make things more easy to understand.
To register or resolve a PNRP record, one has to calculate the PNRP ID of the record beforehand.
A PNRP ID is a 256 bit integer which consists of 2 128 bit integers, the P2PID and the ServiceLocation.
The P2PID is calculated using the follwing formula:
ClassifierHash = SHA-1(Classifier)
P2PID = First 16 bytes(SHA-1(ClassifierHash, BinaryAuthority, ClassifierHash, "PNRP"))
To create the P2PID for a unsecure record, all you need is the Classifier, the BinaryAuthority is zero.
in certain messages, the Authority is the hex representation of the BinaryAuthority.
To calculate the PNRP ID the 160 bit P2PID is shortened to 128 bit and concatended with the ServiceLocation.1)
PNRP ID = (P2PID << 128) | ServiceLocation
The ServiceLocation consists of some bits of a local IPv6 address, and random values, so it is rather easy to create.
The unsecure record “test.pnrp.net” has
would result in the PNRP record
“2095210013f5e694cf5703a3f18ef64c.00000000000000000000000000000000”.
A secure record “428fed1c3a15ecad4b66ec96935dea8547d32fac.test” again with a zero ServiceLocation would result in the PNRP record
“0187eecfc3960f77df14e5fd132f8d07.00000000000000000000000000000000”.
The representation is in hexadecimal and the ”.” is just a helper for the human eye to distiguish the P2P part and the ServiceLocation.
Of course it is not that easy, the Classifier has to be a UTF16 string (in little endian order I guess), so one has to convert ascii to unicode (using iconv) before running any hashing operations on it.
PNRP IDs are considered unsigned 256 bit numbers, and the numberspace is a circle, so the distance from the max PNRP ID to the min PNRP ID is 1.
Before we can register or resolve a PNRP record, we have to join the cloud.
To join the cloud, we have to bootstrap, bootstrapping provides some initial peers, which are queried and stored locally, so they can be used to register and resolve.
To keep things short, many things are not considered here, including
The first step in bootstrapping PNRP is resolving the AAAA records for “PNRPV2.IPV6.MICROSOFT.COM” or “PNRPV21.IPV6.MICROSOFT.COM”. 4)
These domains will return some -from my experience three- initial peers.
dig AAAA PNRPV2.IPV6.MICROSOFT.COM
; <<>> DiG 9.6.1-P2 <<>> AAAA PNRPV2.IPV6.MICROSOFT.COM
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22825
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;PNRPV2.IPV6.MICROSOFT.COM. IN AAAA
;; ANSWER SECTION:
PNRPV2.IPV6.MICROSOFT.COM. 3600 IN AAAA 2002:5ef5:4cfa::5ef5:4cfa
PNRPV2.IPV6.MICROSOFT.COM. 3600 IN AAAA 2002:4137:97fa::4137:97fa
PNRPV2.IPV6.MICROSOFT.COM. 3600 IN AAAA 2002:4137:a9fa::4137:a9fa

Copyright (C) 2011 Microsoft Corporation. 5)
In order to learn about our initial peers, we have to send them a SOLICIT message 6) 7).
to 2002:5ef5:4cfa::5ef5:4cfa
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x1dfcbed4
Message SOLICIT
FieldID=0x92
Length=24 (0x18)
Field Hashed Nonce
HashedNonce
dumping 20 bytes from 0x6e76990
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: A5-C3 9F-F5 5E-FF 24-6D 80-BC 72-D5 74-4E 9B-A9 ....^.$m ..r.tN..
0010: EB-7D 77-FC - - - - - - .}w.
The peer will reply with an ADVERTISE 8) message 9).
from 2002:5ef5:4cfa::5ef5:4cfa
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x6856b90f
Message ADVERTISE
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 1dfcbed4
FieldID=0x60
Length=172 (0xac)
Field ID Array
NumEntries 5
ArrayLength 168
ElementFieldType 0x0030
EntryLength 32
ID d19a6be2e76db4b658750c7b27f13bd1.e3f6fd24a54baa91e7fc681c8e395e23
ID e43c723834806dca9c644923bac4b52b.b8a6b486c7d51c3c14804d04dc0c7879
ID 26db7ed08fb94624555a0989377e7484.fba217509e434b4a711cb58bc43af5fd
ID c520ae989981de9d3eaff8401e59baa1.77006600550044009ada7c4eacc545ed
ID f4543cccbc70623814f9b62406eec2e4.792c173a3fbc620ba7372eb40cd554b4
FieldID=0x92
Length=24 (0x18)
Field Hashed Nonce
HashedNonce
dumping 20 bytes from 0x6e78e30
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: A5-C3 9F-F5 5E-FF 24-6D 80-BC 72-D5 74-4E 9B-A9 ....^.$m ..r.tN..
0010: EB-7D 77-FC - - - - - - .}w.
Upon receiving the ADVERTISE message, we compile REQUEST 10) message for the advertised PNRP IDs and send them to the peers.
11)
to 2002:5ef5:4cfa::5ef5:4cfa
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x304bd5a4
Message REQUEST
FieldID=0x93
Length=20 (0x14)
Field Nonce
Nonce
dumping 16 bytes from 0x6e7d210
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: FB-B3 A8-5A 58-68 60-2E B2-66 BF-B3 E0-75 D9-1A ...ZXh`. .f...u..
FieldID=0x60
Length=172 (0xac)
Field ID Array
NumEntries 5
ArrayLength 168
ElementFieldType 0x0030
EntryLength 32
ID d19a6be2e76db4b658750c7b27f13bd1.e3f6fd24a54baa91e7fc681c8e395e23
ID e43c723834806dca9c644923bac4b52b.b8a6b486c7d51c3c14804d04dc0c7879
ID 26db7ed08fb94624555a0989377e7484.fba217509e434b4a711cb58bc43af5fd
ID c520ae989981de9d3eaff8401e59baa1.77006600550044009ada7c4eacc545ed
ID f4543cccbc70623814f9b62406eec2e4.792c173a3fbc620ba7372eb40cd554b4
The peers will ACK 12) our REQUEST and send us a FLOOD 13) message 14).
from 2002:5ef5:4cfa::5ef5:4cfa
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x6856c8b7
Message ACK
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 304bd5a4
from 2002:5ef5:4cfa::5ef5:4cfa
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x6856c913
Message FLOOD
FieldID=0x43
Length=7 (0x7)
Field Flood Controls
D=1
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 00000000000000000000000000000000.00000000000000000000000000000000
FieldID=0x9a
Length=74 (0x4a)
Field Routing Entry
RouteEntry
ID e43c723834806dca9c644923bac4b52b.b8a6b486c7d51c3c14804d04dc0c7879
Version 4.0
PortNumber 3540
Flags 0x0000
AddressCount 2
Address 2002:4a43:23de:e472:66:7e5:12ea:33bd
Address 2001:0:4137:9e76:24cd:2f85:b5bc:dc21
FieldID=0x9e
Length=30 (0x1e)
Field IPv6 EndPoint Array
NumEntries 1
ArrayLength 26
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2002:5ef5:4cfa::5ef5:4cfa]:3540
On receive of the FLOOD message 15)16), we validate the ROUTE_ENTRY contained in the FLOOD message by sending an INQUIRE 17) message 18) to the corresponding peer.
to 2002:4a43:23de:e472:66:7e5:12ea:33bd
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0xb62d7d7
Message INQUIRE
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0018
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID e43c723834806dca9c644923bac4b52b.b8a6b486c7d51c3c14804d04dc0c7879
FieldID=0x93
Length=20 (0x14)
Field Nonce
Nonce
dumping 16 bytes from 0x6e98620
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: AC-88 96-5F 68-0B 39-82 AF-82 06-2E 70-A9 0C-93 ..._h.9. ....p...
The peer will reply to the INQUIRE message with an AUTHORITY message 19) 20).
We verify the AUTHORITY message and add the new gained information about our peers registered PNRP ids to our cache 21)
22).
from 2002:4a43:23de:e472:66:7e5:12ea:33bd
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x5e94a578
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 0b62d7d7
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 475
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x9b
Length=467 (0x1d3)
Field Validate CPA
Field Encoded CPA
CPALength 463
CPAVersion 2.0
PnrpVersion 4.0
Flags 0x04
NotAfter [28-03-2011 21:18:11]
ServiceLocation
dumping 16 bytes from 0x6f5e990
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 79-78 0C-DC 04-4D 80-14 3C-1C D5-C7 86-B4 A6-B8 yx...M.. <.......
Field Nonce
Nonce
dumping 16 bytes from 0x6f5ea50
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: AC-88 96-5F 68-0B 39-82 AF-82 06-2E 70-A9 0C-93 ..._h.9. ....p...
BinaryAuthority
dumping 20 bytes from 0x6f5e9a8
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: F8-0B 2C-09 D1-DE 4D-08 25-6E 07-74 6D-FC EB-3A ..,...M. %n.tm..:
0010: B5-39 DF-98 - - - - - - .9..
Field Service Address List
NumServiceAddresses 2
ServiceAddressLength 18
IPv6 EndPoint
[2002:4a43:23de:e472:66:7e5:12ea:33bd]:3540
IPv6 EndPoint
[2001:0:4137:9e76:24cd:2f85:b5bc:dc21]:3540
NumPayloads 1
TotalBytes 50
Field Payload
Type 00000001
DataLength 40
Field IPv6 App EndPoint
[2002:4a43:23de:e472:66:7e5:12ea:33bd]:0 (6)
Field IPv6 App EndPoint
[2001:0:4137:9e76:24cd:2f85:b5bc:dc21]:0 (6)
Field CPA Public Key
FieldLength 169
AlgorithmObjIdLength 20
PublicKeycbData 140
AlgorithmObjId
dumping 20 bytes from 0x6f5edd0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 31-2E 32-2E 38-34 30-2E 31-31 33-35 34-39 2E-31 1.2.840. 113549.1
0010: 2E-31 2E-31 - - - - - - .1.1
PublicKeyData
dumping 140 bytes from 0x6f5ee30
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 30-81 89-02 81-81 00-CB 14-67 C3-84 6A-09 29-F2 0....... .g..j.).
0010: E5-E1 11-7E 5E-69 9E-D2 A2-DD 0E-4A 67-84 77-FD ...~^i.. ...Jg.w.
0020: 59-9E 5A-2E 3A-86 36-92 F6-1F 42-C8 96-A3 AB-5C Y.Z.:.6. ..B....\
0030: 8C-5E 4A-29 15-E0 D2-8C 94-BF 7C-06 A5-91 CA-7E .^J).... ..|....~
0040: F9-47 4F-FB 4C-AD A0-4F 61-D6 8C-00 03-76 DB-C3 .GO.L..O a....v..
0050: 4B-DE 30-A4 64-51 98-45 F7-0A EF-E8 BB-31 0E-7D K.0.dQ.E .....1.}
0060: 1F-E8 0C-FF AF-C1 42-C7 B3-D6 40-B6 62-E5 3E-CB ......B. ..@.b.>.
0070: 5D-9A 4C-11 CC-B8 F5-DB 01-1F A5-25 5D-6E A3-85 ].L..... ...%]n..
0080: 87-74 A0-15 7D-7B F1-02 03-01 00-01 - - .t..}{.. ....
Field Signature
FieldLength 136
SignatureLength 128
ALG_ID 0x8004
SignatureData
dumping 128 bytes from 0x6f5ef50
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: C4-4C FB-F3 EA-29 E9-5E 9E-E1 13-88 49-01 D9-A0 .L...).^ ....I...
0010: EA-90 C2-CC CD-49 25-39 49-2A 5F-53 E9-90 6C-DF .....I%9 I*_S..l.
0020: F9-FB 81-92 FA-7D 21-E6 48-1E AF-B0 5C-9D CF-0B .....}!. H...\...
0030: 1F-0D A0-42 D5-22 5F-BD E8-BC 2C-28 84-0F 4B-3B ...B."_. ..,(..K;
0040: 9D-7D D8-E8 85-D6 17-C6 55-D9 DA-76 F7-38 AF-EB .}...... U..v.8..
0050: 09-83 BD-AC A8-25 F2-E2 8C-37 DD-FC 5B-7F 9F-A1 .....%.. .7..[...
0060: 27-A5 68-6E 5C-81 49-8F A2-1D B4-6A FA-C1 3C-FD '.hn\.I. ...j..<.
0070: 64-0E F8-42 44-B0 92-FE CE-91 53-12 A1-1F 83-88 d..BD... ..S.....
Now, we have to verify the CPA (Certified Peer Address)
a nonzero BinaryAuthority is present in the CPA
the BinaryAuthority is a SHA-1 hash of the public key included in the CPA
Verifying INQUIRE
The computed PNRP ID matches the PNRP ID in the ROUTE_ENTRY
Signature is valid
As all requirements are met, we can “Add the Route Entry to the Route Entry Cache”.
Now we have a PNRP ID in our Route Entry Cache associated with two peer addresses.
e43c723834806dca9c644923bac4b52b.b8a6b486c7d51c3c14804d04dc0c7879
2002:4a43:23de:e472:66:7e5:12ea:33bd
2001:0:4137:9e76:24cd:2f85:b5bc:dc21
To resolve a PNRP record 23) 24), we calculate the PNRP ID of the record as outlined already, and send a LOOKUP message to a peer from our cache which has an PNRP id registered which is closest to the one we want to resolve, the peer will reply with an AUTHORITY message with PNRP IDs and associated peers which are closer to the to-be-resolved ID than the replying peer itself.
We continue to query these hops with LOOKUP messages until we found the record we want to resolve, once found, we send an INQUIRE message to the peer associated.
The peer will reply with an AUTHORITY message, and we are done.

Copyright (C) 2011 Microsoft Corporation 25)
In this case, we want to resolve the unsecure PNRP record 0.0805B99A53BD38B0459808EC9F861935.
The calculated PNRP ID is 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000.
Given the length of the IDs, we will refer to this as TargetPNRPID.
To start with, our route cache looks like this:
f066311aff25ab422218f75de497b7dc.fd685a845fb774d4a03e2f01d7ad8084
2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b
f4543cccbc70623814f9b62406eec2e4.af550ca0b95b3adddb3a81b6c1754cb0
2001:0:5ef5:79fd:a9:f80:ae51:76b0
As f066311aff25ab422218f75de497b7dc.fd685a845fb774d4a03e2f01d7ad8084 is closer to our TargetPNRPID, we query 2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b by sending a LOOKUP message with our TargetPNRPID and the PNRP ID we associate with the peer as ValidatePNRPID.
to 2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x51fbafaf
Message LOOKUP
FieldID=0x45
Length=12 (0xc)
Field Lookup Controls
Flags 0x0000
Precision 0
ResolveCriteria 1
ResolveReasonCode 0
FieldID=0x38
Length=36 (0x24)
Field Target PNRP ID
TargetPNRPID 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID f066311aff25ab422218f75de497b7dc.fd685a845fb774d4a03e2f01d7ad8084
FieldID=0x9e
Length=30 (0x1e)
Field IPv6 EndPoint Array
NumEntries 1
ArrayLength 26
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2001:2:2:2:2:2:2:2]:3540
The ValidatePNRPID is registered on the peer, and he even knows a closer match, providing the details he knows about the closer match.
from 2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x127c715a
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 51fbafaf
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 82
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x9a
Length=74 (0x4a)
Field Routing Entry
RouteEntry
ID 7508690d596d035e1e326348b0544916.813081444818315ce18eed1b9daedbd1
Version 4.0
PortNumber 3540
Flags 0x0000
AddressCount 2
Address 2002:d851:3491::d851:3491
Address 2001:0:4137:9e76:30bb:bb3:27ae:cb6e
So, we query the closer match, using the closer matches ID as ValidatePNRPID.
to 2002:d851:3491::d851:3491
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0xe61de8e
Message LOOKUP
FieldID=0x45
Length=12 (0xc)
Field Lookup Controls
Flags 0x0000
Precision 0
ResolveCriteria 1
ResolveReasonCode 0
FieldID=0x38
Length=36 (0x24)
Field Target PNRP ID
TargetPNRPID 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 7508690d596d035e1e326348b0544916.813081444818315ce18eed1b9daedbd1
FieldID=0x9e
Length=48 (0x30)
Field IPv6 EndPoint Array
NumEntries 2
ArrayLength 44
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2001:2:2:2:2:2:2:2]:3540
IPv6 EndPoint
[2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b]:3540
Once again, the peer can help us, providing a even closer match.
from 2002:d851:3491::d851:3491
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0xea87676
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 0e61de8e
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 66
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x9a
Length=58 (0x3a)
Field Routing Entry
RouteEntry
ID 59746f3afa6fadb939cb40b1615f43c2.fbec5ed7f2025e4d1aca358ff888b6e6
Version 4.0
PortNumber 3540
Flags 0x0000
AddressCount 1
Address 2001:0:4137:9e76:3ce6:134a:b96b:23ef
We compare the distance(CurrentBestMatch,TargetPNRPID) to the last peers distance(ValidatePNRPID,TargetPNRPID) and as the last peers ValidatePNRPID is closer, we have a new CurrentBestMatch.
cnh 7508690d596d035e1e326348b0544916.813081444818315ce18eed1b9daedbd1
cbm f066311aff25ab422218f75de497b7dc.fd685a845fb774d4a03e2f01d7ad8084
dist a 20a69cb42b4d467d9755e12e2be16e8c.813081444818315c618eed1b9daedbd1
dist b 63fb9b3e2efa119e64c38abc9fdb22ad.0297a57ba0488b2bdfc1d0fe28527f7c
CurrentBestMatch 7508690d596d035e1e326348b0544916.813081444818315ce18eed1b9daedbd1
Then we query the peer we learned about …
to 2001:0:4137:9e76:3ce6:134a:b96b:23ef
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x45f80f6
Message LOOKUP
FieldID=0x45
Length=12 (0xc)
Field Lookup Controls
Flags 0x0000
Precision 0
ResolveCriteria 1
ResolveReasonCode 0
FieldID=0x38
Length=36 (0x24)
Field Target PNRP ID
TargetPNRPID 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 59746f3afa6fadb939cb40b1615f43c2.fbec5ed7f2025e4d1aca358ff888b6e6
FieldID=0x9e
Length=66 (0x42)
Field IPv6 EndPoint Array
NumEntries 3
ArrayLength 62
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2001:2:2:2:2:2:2:2]:3540
IPv6 EndPoint
[2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b]:3540
IPv6 EndPoint
[2002:d851:3491::d851:3491]:3540
The peer provides a closer match again:
from 2001:0:4137:9e76:3ce6:134a:b96b:23ef
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x5a5febec
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 045f80f6
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 66
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x9a
Length=58 (0x3a)
Field Routing Entry
RouteEntry
ID 548c9347aa0042f61815c5736945002a.77006600550044006d60eb2054a53beb
Version 4.0
PortNumber 3540
Flags 0x0000
AddressCount 1
Address 2001:0:4137:9e76:1062:16ea:b9c8:2f03
Again, we update our CurrentBestMatch:
cnh 59746f3afa6fadb939cb40b1615f43c2.fbec5ed7f2025e4d1aca358ff888b6e6
cbm 7508690d596d035e1e326348b0544916.813081444818315ce18eed1b9daedbd1
dist a 0512a2e1cc4ff0d8b2eebe96dcec6938.fbec5ed7f2025e4c9aca358ff888b6e6
dist b 20a69cb42b4d467d9755e12e2be16e8c.813081444818315c618eed1b9daedbd1
CurrentBestMatch 59746f3afa6fadb939cb40b1615f43c2.fbec5ed7f2025e4d1aca358ff888b6e6
And query the new provided peer:
to 2001:0:4137:9e76:1062:16ea:b9c8:2f03
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x50c3d60
Message LOOKUP
FieldID=0x45
Length=12 (0xc)
Field Lookup Controls
Flags 0x0000
Precision 0
ResolveCriteria 1
ResolveReasonCode 0
FieldID=0x38
Length=36 (0x24)
Field Target PNRP ID
TargetPNRPID 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 548c9347aa0042f61815c5736945002a.77006600550044006d60eb2054a53beb
FieldID=0x9e
Length=84 (0x54)
Field IPv6 EndPoint Array
NumEntries 4
ArrayLength 80
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2001:2:2:2:2:2:2:2]:3540
IPv6 EndPoint
[2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b]:3540
IPv6 EndPoint
[2002:d851:3491::d851:3491]:3540
IPv6 EndPoint
[2001:0:4137:9e76:3ce6:134a:b96b:23ef]:3540
The new provided peer provides a even closer match:
from 2001:0:4137:9e76:1062:16ea:b9c8:2f03
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0xf2142aa4
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 050c3d60
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 82
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x9a
Length=74 (0x4a)
Field Routing Entry
RouteEntry
ID 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
Version 4.0
PortNumber 3540
Flags 0x0000
AddressCount 2
Address 2001:0:4137:9e76:2814:ef4:a225:b675
Address 2001:1:1:1:1:1:1:1
We update our CurrentBestMatch:
cnh 548c9347aa0042f61815c5736945002a.77006600550044006d60eb2054a53beb
cbm 59746f3afa6fadb939cb40b1615f43c2.fbec5ed7f2025e4d1aca358ff888b6e6
dist a 002ac6ee7be0861591394358e4d225a0.77006600550043ffed60eb2054a53beb
dist b 0512a2e1cc4ff0d8b2eebe96dcec6938.fbec5ed7f2025e4c9aca358ff888b6e6
CurrentBestMatch 548c9347aa0042f61815c5736945002a.77006600550044006d60eb2054a53beb
And query the peer:
to 2001:1:1:1:1:1:1:1
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x4ac724fd
Message LOOKUP
FieldID=0x45
Length=12 (0xc)
Field Lookup Controls
Flags 0x0000
Precision 0
ResolveCriteria 1
ResolveReasonCode 0
FieldID=0x38
Length=36 (0x24)
Field Target PNRP ID
TargetPNRPID 5461cc592e1fbce086dc821a8472da8a.00000000000000008000000000000000
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
FieldID=0x9e
Length=102 (0x66)
Field IPv6 EndPoint Array
NumEntries 5
ArrayLength 98
ElementFieldType 0x009d
EntryLength 18
IPv6 EndPoint
[2001:2:2:2:2:2:2:2]:3540
IPv6 EndPoint
[2a01:e35:8a57:f4e0:cd61:94a2:91f0:cf4b]:3540
IPv6 EndPoint
[2002:d851:3491::d851:3491]:3540
IPv6 EndPoint
[2001:0:4137:9e76:3ce6:134a:b96b:23ef]:3540
IPv6 EndPoint
[2001:0:4137:9e76:1062:16ea:b9c8:2f03]:3540
The peer replies is does not now the ValidatePNRPID which we had associated with this peer.
from 2001:1:1:1:1:1:1:1
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x97059714
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 4ac724fd
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 6
Offset 0
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0200
We update our CurrentBestMatch …
cnh 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
cbm 548c9347aa0042f61815c5736945002a.77006600550044006d60eb2054a53beb
dist a 00000000000000000000000000000000.28a3d2d92f92dc1e181baf7cdb2f79ee
dist b 002ac6ee7be0861591394358e4d225a0.77006600550043ffed60eb2054a53beb
CurrentBestMatch 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
And as the distance to the CurrentBestMatch satisfies the ResolveCriteria, we actually resolved the PNRPID, now we have to send the peer an INQUIRE message:
to 2001:0:4137:9e76:2814:ef4:a225:b675
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x7366c238
Message INQUIRE
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x001c
FieldID=0x39
Length=36 (0x24)
Field Validate PNRP ID
ValidatePNRPID 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
FieldID=0x93
Length=20 (0x14)
Field Nonce
Nonce
dumping 16 bytes from 0x709a6f0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: BF-03 73-71 0D-B3 4E-E8 E9-41 9D-EA 26-59 3A-DE ..sq..N. .A..&Y:.
As the AUTHORITY_BUFFER in the AUTHORITY response of the peer is larger than 1188 bytes, it is fragmented in two parts, we receive the first part:
from 2001:0:4137:9e76:2814:ef4:a225:b675
found 1188 bytes fragment
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x97059732
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 7366c238
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 1406
Offset 0
Fragment
dumping 1188 bytes from 0x709d090
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 00-40 00-06 00-00 00-00 00-85 00-4C 00-20 00-48 .@...... ...L. .H
...
04a0: 07-AA 92-41 - - - - - - ...A
and the second part:
from 2001:0:4137:9e76:2814:ef4:a225:b675
FieldID=0x10
Length=12 (0xc)
Field Header
Identifier=81
Version=4.0
MessageID=0x97059732
Message AUTHORITY
FieldID=0x18
Length=8 (0x8)
Field Header Acked
Acked Message ID 7366c238
FieldID=0x98
Length=8 (0x8)
Field Split Controls
Size 1406
Offset 1188
Fragment
dumping 218 bytes from 0x70ad390
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 30-41 47-FA C2-EC AE-9E 41-33 31-4B F7-8C 8A-BB 0AG..... A31K....
...
00d0: C4-38 80-F9 6D-64 03-CF 39-A3 - - - .8..md.. 9.
and reassemble the AUTHORITY_BUFFER
Field AUTHORITY_BUFFER
FieldID=0x40
Length=6 (0x6)
Field Flags Field
flags 0x0000
FieldID=0x85
Length=76 (0x4c)
Field Classifier
NumEntries 32
ArrayLength 72
ElementFieldType 0x0084
EntryLength 2
Data
dumping 64 bytes from 0x70b2170
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 00-30 00-38 00-30 00-35 00-42 00-39 00-39 00-41 .0.8.0.5 .B.9.9.A
0010: 00-35 00-33 00-42 00-44 00-33 00-38 00-42 00-30 .5.3.B.D .3.8.B.0
0020: 00-34 00-35 00-39 00-38 00-30 00-38 00-45 00-43 .4.5.9.8 .0.8.E.C
0030: 00-39 00-46 00-38 00-36 00-31 00-39 00-33 00-35 .9.F.8.6 .1.9.3.5
FieldID=0x5a
Length=870 (0x366)
Field Extended Payload
Length 866
MinorVersion 0
MajorVersion 2
SignatureOffset 0
NotAfter [30-03-2011 09:39:09]
ID 5461cc592e1fbce086dc821a8472da8a.28a3d2d92f92dc1e981baf7cdb2f79ee
Field Nonce
Nonce
dumping 16 bytes from 0x70b22c0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: BF-03 73-71 0D-B3 4E-E8 E9-41 9D-EA 26-59 3A-DE ..sq..N. .A..&Y:.
NumberOfPayloads 1
TotalPayloadBytes 666
PayloadType 0x80000003
PayloadLength 656
PayloadData
dumping 656 bytes from 0x70b2340
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 05-79 17-A0 FE-D8 8C-C5 81-00 F6-3F EC-30 1A-8A .y...... ...?.0..
...
0280: 8C-96 5D-A0 06-D6 DB-B5 31-27 BE-65 80-E2 0F-85 ..]..... 1'.e....
Field Signature
FieldLength 136
SignatureLength 128
ALG_ID 0x8004
SignatureData
dumping 128 bytes from 0x70b2660
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 97-C9 7B-A9 A8-F2 1A-09 54-1C E7-A0 16-F8 4C-FC ..{..... T.....L.
0010: 6B-34 6D-1F A7-E8 FB-44 8A-64 58-43 55-2B 53-13 k4m....D .dXCU+S.
0020: 11-57 C9-F9 1C-6D B3-7B 97-CE A4-DC 2E-0E E3-07 .W...m.{ ........
0030: 74-48 64-51 93-84 57-3E 14-DE F5-FA B8-06 AC-1E tHdQ..W> ........
0040: A7-BF 2A-71 95-CE 46-CD C8-0C 0F-CA A8-7B AE-A9 ..*q..F. .....{..
0050: C3-AE C1-73 18-FA 33-65 1D-39 E9-89 6C-78 A4-53 ...s..3e .9..lx.S
0060: 50-ED 3E-CE C4-3A 85-13 59-4F 10-69 2B-94 7F-B9 P.>..:.. YO.i+...
0070: 72-F3 45-A3 A9-50 69-5C 70-15 AB-4F 66-F8 B3-00 r.E..Pi\ p..Of...
FieldID=0x9b
Length=450 (0x1c2)
Field Validate CPA
Field Encoded CPA
CPALength 446
CPAVersion 2.0
PnrpVersion 4.0
Flags 0x3a
NotAfter [30-03-2011 09:39:09]
ServiceLocation
dumping 16 bytes from 0x70b27d0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: EE-79 2F-DB 7C-AF 1B-98 1E-DC 92-2F D9-D2 A3-28 .y/.|... .../...(
Field Nonce
Nonce
dumping 16 bytes from 0x70b2890
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: BF-03 73-71 0D-B3 4E-E8 E9-41 9D-EA 26-59 3A-DE ..sq..N. .A..&Y:.
ClassifierHash
dumping 20 bytes from 0x70b27fc
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: C4-BE 80-80 A7-7B 0A-C5 B1-09 1C-EF 59-B7 E9-94 .....{.. ....Y...
0010: 5F-B8 30-60 - - - - - - _.0`
FriendlyNameLen 1
FriendlyName
dumping 1 bytes from 0x70b28e0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 31- - - - - - - - 1
Field Service Address List
NumServiceAddresses 2
ServiceAddressLength 18
IPv6 EndPoint
[2001:0:4137:9e76:2814:ef4:a225:b675]:3540
IPv6 EndPoint
[2001:1:1:1:1:1:1:1]:3540
NumPayloads 1
TotalBytes 30
Field Payload
Type 00000001
DataLength 20
Field IPv6 App EndPoint
[2001:0:4137:9e76:2814:ef4:a225:b675]:0 (6)
Field CPA Public Key
FieldLength 169
AlgorithmObjIdLength 20
PublicKeycbData 140
AlgorithmObjId
dumping 20 bytes from 0x70b2c00
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 31-2E 32-2E 38-34 30-2E 31-31 33-35 34-39 2E-31 1.2.840. 113549.1
0010: 2E-31 2E-31 - - - - - - .1.1
PublicKeyData
dumping 140 bytes from 0x70b2c60
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 30-81 89-02 81-81 00-D1 F7-ED 16-51 26-10 49-61 0....... ...Q&.Ia
0010: E7-D8 F9-20 FE-24 AC-5A EA-50 9E-56 80-74 9D-51 ... .$.Z .P.V.t.Q
0020: 6C-96 9E-4B 95-4A 1E-72 1D-D1 D4-96 4A-CE 42-22 l..K.J.r ....J.B"
0030: F2-54 A4-D2 57-BB 07-AA 92-41 30-41 47-FA C2-EC .T..W... .A0AG...
0040: AE-9E 41-33 31-4B F7-8C 8A-BB 09-AC 1E-F7 6E-6C ..A31K.. ......nl
0050: CD-54 C0-56 95-4D 85-F1 4D-1F B8-2B 00-50 6B-A8 .T.V.M.. M..+.Pk.
0060: 2C-24 DF-87 69-44 CD-D8 D7-B2 88-8C 0E-61 2D-FE ,$..iD.. .....a-.
0070: A8-0B 50-28 3B-2B 9F-9E 3F-A1 EA-FD D0-5D FA-A9 ..P(;+.. ?....]..
0080: 52-28 52-F4 A5-58 EB-02 03-01 00-01 - - R(R..X.. ....
Field Signature
FieldLength 136
SignatureLength 128
ALG_ID 0x8004
SignatureData
dumping 128 bytes from 0x70b2d80
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: D1-26 1B-D6 5D-32 D1-69 6E-CA 26-68 E6-11 01-16 .&..]2.i n.&h....
0010: 2D-F5 39-8F C7-E7 CC-80 97-B2 32-A4 DE-88 D1-9F -.9..... ..2.....
0020: 01-9B 3F-3C 21-95 5C-DF 7F-07 88-99 1E-27 41-C0 ..?<!.\. .....'A.
0030: 79-5C 59-CD 64-12 2F-16 AE-E8 B0-D3 AB-82 DA-0B y\Y.d./. ........
0040: D7-F7 53-80 0A-68 BA-FD 1E-A3 0D-CC F0-14 90-03 ..S..h.. ........
0050: AC-41 07-7E 72-CA 86-DF 32-5A 17-6C 92-C2 08-2B .A.~r... 2Z.l...+
0060: 40-86 E6-E1 8C-B6 01-C4 9E-7D 93-A8 09-B6 AD-92 @....... .}......
0070: 7A-C1 D0-41 0A-D6 C4-38 80-F9 6D-64 03-CF 39-A3 z..A...8 ..md..9.
We need to verify the CPA:
We resolved.
Registering a record is basically the same as resolving a record, only difference is in the ResolveReasonCode 26).
Therefore there is no example, but screen shots of resolves for my first successful registered records.
I used 2001:dead:babe:eed:c0ffee:0:2 for the PAYLOAD, as it is easy to identify.

My first unsecure record resolved properly.

My first secure record resolved properly.
While I can verify EXTENDED_PAYLOAD received from peers and create own EXTENDED_PAYLOADs which pass my own verification, they seem to be malformed, as records which have an EXTENDED_PAYLOAD are ignored by peers. A real pitty, as the EXTENDED_PAYLOAD allows emedding a 4096 bytes large binary object.
While I did not use the Windows API myself, the official documentation has some easy to use examples how to use PNRP 27).
For secure records you have figured out how to use the Cryptography Functions 28), provide a meaningful HCRYPTPROV to PeerIdentityCreate 29), and register your record using PeerPnrpRegister 30) 31). Alternatively you can use Peer Group - Identities 32) to create an Identity, even export it easily, and register a secure record using your created Identity via netsh.
For whatever reason there is no way to c&p within netsh …
Some commands to start with:
netsh p2p pnrp cloud show names
netsh p2p pnrp peer resolve 0.test Global_
netsh p2p pnrp peer add registration 0.test

This software can be used to create/import/export the Identity which is required to create a secure record.

Registration of the secure record using netsh.
PNRP is used by the Easy Connect option of Remote Assist on Windows 7.
The 12 characters long password is used to create a unsecure PNRP record which is published in the cloud, after you communicated this password to your remote assistant, his computer will calcuate the name of the record, resolve it, decrypt the Remote Administration Ticket and connect to host using the credentials from the decrypted ticket.
The first 6 chars are used to calculate the PNRP record using the steps outlined in 3.2.5.1 33) and 3.1.5.3 34) and 4.2 35) provides an example which can be used to verify own implementations.
Calculating the PNRP record includes the hours since EPOCH, and to make sure bad clocks on your computer do not mess things up, the records within a 3 hour range get resolved until first match 36).
Given the password 6QK2MF8PXN3H, the PNRP record is derived from 6QK2MF and results in 0.4B6B905C2E3271FA4100AF8D18434F26.
Additionally the first 6 chars are used to derive the AES session key which is required to decrypt the Remote Administration Ticket in the EXTENDED_PAYLOAD, the remaining 6 chars serve as a password for the session.
Deriving this session key from the 6 chars includes the hours since EPOCH too.
Given 6QK2MF the AES-128-CBC key for the EXTENDED_PAYLOAD is
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: A4-9B 8F-6A 06-93 B3-F8 D5-E2 BA-D5 33-74 92-D2 ...j.... ....3t..
The documentation
37) 38) an example provided 39) was slightly misleading.
After decrypting properly, the ticket looks like this 40)
<E>
<A KH="YiKwWUY8Ioq5NB3wAQHSbs5kwrM=" ID="8rYm30RBW8/4dAWoUsWbFCF5jno/7jr5tNpHQc2goLbw4uuBBJvLsU02YYLlBMg5"/>
<C>
<T ID="1" SID="1440550163">
<L P="49749" N="2001:4898:1a:5:79e2:3356:9b22:3470"/>
<L P="49751" N="172.31.250.64"/>
</T>
</C>
</E>
After connecting the remote, both peers can exchange contact information 41), which allows using secure PNRP records for repeated sessions and allows to create a Remote Assistance Session without a password.
Connecting the peer with rdesktop does not work, as rdesktop lacks the Remote Assist protocol features, maybe -rdesktops successor- freerdp will pick this up some day, for now I failed to lookup useable information on how to use the KH and ID information from the ticket.
Windows Remote Assist is really great, it is easy to use, requires no additional software and works great. The only thing missing is a 'NAT Traversal mode' where your 'novice' client connects to your central help desk server and can be dispatched to an 'expert' who wants to help out then.

PNRP Beacon 42) is a little program published next to an article about PNRP 43).
The software uses the EXTENDED_PAYLOAD to publish a string with a short description of the publishing machine:
NumberOfPayloads 1
TotalPayloadBytes 65
PayloadType 0x80000003
PayloadLength 55
PayloadData
dumping 55 bytes from 0x7fb51d0
0 1 2 3 4 5 6 7 8 9 A B C D E F 01234567 89ABCDEF
0000: 43-4F 4D-4D 4F-4E 2D-50 43-2C 20-4D 69-63 72-6F COMMON-P C, Micro
0010: 73-6F 66-74 20-57 69-6E 64-6F 77-73 20-4E 54-20 soft Win dows NT
0020: 36-2E 31-2E 37-36 30-30 2E-30 2C-20 43-50 55-20 6.1.7600 .0, CPU
0030: 43-6F 75-6E 74-3A 31- - - - - Count:1
While I usually prefer Wireshark, I started using Network Monitor for looking on PNRP traffic, as
Network Monitor is the only software I'm aware of to decode PNRP packets.
I was not convinced by the .cap fileformat, but editcap nicely converted Network Monitor .cap files to .pcap.
The Network Parsing Language used by Network Monitor was impressive too, the parsers for Network Monitor are simple text files which can edited and used without having to recompile something, and they even have a Subversion repository on Codeplex 44) for it.
Unfortunately I'm not aware of any other software but Network Monitor to understand the Network Parsing Language, would be great to be able to use the NPL parsers in Wireshark.
For me the PNRP parser failed to reassemble fragmented AUTHORITY_BUFFERS, as they span multiple packets, I do not know if this is a limitation of the NPL or just a missing feature in the parser, as the NPL documentation is hidden in some barely useable help files.
When I first heard about PNRP I was expecting some software to use it, some research to happen, people coming up with numbers, maybe even code.
Even though PNRP exists for about 7 years now, starting with Windows XP SP2, there was basically nothing, not even a Wireshark Dissector, and I decided to have a look myself.
I'd say PNRP is a pretty reasonable protocol, it does a really good job at exactly what it was designed for, the existing documentation is good -even though I'd have appreciated some more words on the cache structure which is used by Windows- but Microsoft somehow failed to convince developers to use it.
At this moment Google Codesearch lists 4 projects for PeerPnrpRegister, and all of those four are not using PNRP, they just wrap it in one or another way, which is a real pitty.
And now, I have to admit I'm slightly afraid this may change, as PNRP is a really attractive for c&c services and there is very little one can do to mitigate secure records published on PNRP.
For DNS based c&c systems, there are established processes to claim the domains and sinkhole the traffic (e.g. Conficker/Rustock), for peer to peer based c&c systems sybil attacks to taint the network (e.g. Stormworm) or implementation bugs could be used for a takeover.
For PNRP secure records, you need the Identity -the RSA keys- to claim a domain, and while publishing the public key is part of the idea, there is no reason to hand out the private key.
Given a single record and lots of time, sybil attacks may be possible on a single PNRP ID, but due to the free choice of the Classifier part of a PNRP record, one can create *many* PNRP IDs using a single Identity.
Following Conficker's example, one could randomly choose 250 of 64k randomly generated Classifiers a day, resulting in 64k different PNRP IDs each day to sybil. For each of these ids, one would have to find multiple close PNRP IDs to allow a sybil attack to taint the networks cache, but a takeover would still be impossible due to the lack of keys.
One could even distribute commands using PNRP, simply store your commands in the Extended Payload of the record, and as you got a private key already, sign the Payload, and have the peer verify this additional signature - just in case.
As PNRP does not cache the Payload of records -contrary to DNS-, running a denial of service attack on precalculated c&c ID's once they register is possible, but as said before generating 250.000 close enough PNRPIDs which would end up in the leaf set of the c&c PNRPID -which is required to get knowledge of the new PNRPID in time- is a real challenge, so I doubt DOS could be used to mitigate c&c PNRPID's in time.
Currently the only thing I can think of to mitigate is shutting down the bootstrap servers at Microsoft, but given I have no idea how resilent PNRP is to this, given it can bootstrap over UPNP additional to using the Microsoft servers, this may even fail.
I think the lack of trust in IPv6 is the main reason this is not used for c&c services at this moment, but as IPv6 adoption is rising and -for those who lack native IPv6- Windows 7 always creates a Teredo IPv6 tunnel, this may just be a matter of time.
CODE is here
very interesting, thanks for sharing. it could be interesting to answer some security vendor what they know about PNRP and if they can detect and normalize this protocol..or maybe not :)