More certificate stuff...

This commit is contained in:
Adam Ierymenko 2020-08-12 21:28:06 -07:00
parent fe01352412
commit 2abf2c5695
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
6 changed files with 83 additions and 7 deletions

View file

@ -586,6 +586,16 @@ ZT_CertificateError Node::addCertificate(
return RR->topology->addCertificate(tptr, c, now, localTrust, true, true, true);
}
ZT_ResultCode Node::deleteCertificate(
void *tptr,
const void *serialNo)
{
if (!serialNo)
return ZT_RESULT_ERROR_BAD_PARAMETER;
RR->topology->deleteCertificate(tptr, reinterpret_cast<const uint8_t *>(serialNo));
return ZT_RESULT_OK;
}
struct p_certificateListInternal
{
Vector< SharedPtr< const Certificate > > c;
@ -1106,6 +1116,18 @@ enum ZT_CertificateError ZT_Node_addCertificate(
}
}
ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
ZT_Node *node,
void *tptr,
const void *serialNo)
{
try {
return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
} catch (...) {
return ZT_RESULT_ERROR_INTERNAL;
}
}
ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
{
try {

View file

@ -147,6 +147,10 @@ public:
const void *certData,
unsigned int certSize);
ZT_ResultCode deleteCertificate(
void *tptr,
const void *serialNo);
ZT_CertificateList *listCertificates();
int sendUserMessage(

View file

@ -242,6 +242,32 @@ ZT_CertificateError Topology::addCertificate(void *tPtr, const Certificate &cert
return ZT_CERTIFICATE_ERROR_NONE;
}
unsigned int Topology::deleteCertificate(void *tPtr,const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE])
{
Mutex::Lock l(m_certs_l);
const unsigned long origCertCount = (unsigned long)m_certs.size();
Map< SHA384Hash, p_CertEntry >::const_iterator c(m_certs.find(SHA384Hash(serialNo)));
if (c != m_certs.end()) {
if ((c->second.certificate->subject.uniqueId) && (c->second.certificate->subject.uniqueIdSize > 0)) {
SHA384Hash uniqueIdHash;
SHA384(uniqueIdHash.data, c->second.certificate->subject.uniqueId, c->second.certificate->subject.uniqueIdSize);
m_eraseCertificate(tPtr, c->second.certificate, &uniqueIdHash);
} else {
m_eraseCertificate(tPtr, c->second.certificate, nullptr);
}
const int64_t now = RR->node->now();
m_cleanCertificates(tPtr, now);
m_writeTrustStore(tPtr);
{
RWMutex::Lock l3(m_peers_l);
RWMutex::Lock l2(m_roots_l);
m_updateRootPeers(tPtr, now);
}
}
return (unsigned int)(origCertCount - (unsigned long)m_certs.size());
}
void Topology::allCerts(Vector< SharedPtr<const Certificate> > &c,Vector< unsigned int > &t) const noexcept
{
Mutex::Lock l(m_certs_l);
@ -296,8 +322,7 @@ void Topology::m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate
for (unsigned int i = 0; i < cert->subject.identityCount; ++i) {
const Identity *const ii = reinterpret_cast<const Identity *>(cert->subject.identities[i].identity);
Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > >::iterator
bySubjectIdentity(m_certsBySubjectIdentity.find(ii->fingerprint()));
Map< Fingerprint, Map< SharedPtr< const Certificate >, unsigned int > >::iterator bySubjectIdentity(m_certsBySubjectIdentity.find(ii->fingerprint()));
if (bySubjectIdentity != m_certsBySubjectIdentity.end()) {
bySubjectIdentity->second.erase(cert);
if (bySubjectIdentity->second.empty())

View file

@ -140,7 +140,23 @@ public:
* @param verify If true, verify certificate and certificate chain (default: true)
* @return Error or 0 on success
*/
ZT_CertificateError addCertificate(void *tPtr, const Certificate &cert, const int64_t now, unsigned int localTrust, bool writeToLocalStore, bool refreshRootSets = true, bool verify = true);
ZT_CertificateError addCertificate(
void *tPtr,
const Certificate &cert,
int64_t now,
unsigned int localTrust,
bool writeToLocalStore,
bool refreshRootSets = true,
bool verify = true);
/**
* Delete certificate
*
* @param tPtr Thread pointer
* @param serialNo Serial number to delete
* @return Number of deleted certificates
*/
unsigned int deleteCertificate(void *tPtr,const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]);
/**
* Fill vectors with all certificates and their corresponding local trust flags
@ -154,11 +170,11 @@ private:
void m_rankRoots(int64_t now);
void m_eraseCertificate(void *tPtr, const SharedPtr< const Certificate > &cert, const SHA384Hash *uniqueIdHash);
bool m_cleanCertificates(void *tPtr, int64_t now);
bool m_verifyCertificateChain(const Certificate *current, const int64_t now) const;
ZT_CertificateError m_verifyCertificate(const Certificate &cert, const int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
bool m_verifyCertificateChain(const Certificate *current, int64_t now) const;
ZT_CertificateError m_verifyCertificate(const Certificate &cert, int64_t now, unsigned int localTrust, bool skipSignatureCheck) const;
void m_loadCached(void *tPtr, const Address &zta, SharedPtr< Peer > &peer);
SharedPtr< Peer > m_peerFromCached(void *tPtr, const Address &zta);
SharedPtr< Path > m_newPath(const int64_t l, const InetAddress &r, const UniqueID &k);
SharedPtr< Path > m_newPath(int64_t l, const InetAddress &r, const UniqueID &k);
void m_updateRootPeers(void *tPtr, int64_t now);
void m_writeTrustStore(void *tPtr);

View file

@ -2407,6 +2407,7 @@ ZT_SDK_API int ZT_Node_tryPeer(
*
* @param node Node instance
* @param tptr Thread pointer to pass to functions/callbacks resulting from this call
* @param now Current time
* @param localTrust Local trust flags (ORed together)
* @param cert Certificate object, or set to NULL if certData and certSize are to be used
* @param certData Certificate binary data if 'cert' is NULL, NULL otherwise

View file

@ -535,11 +535,19 @@ func (n *Node) ListCertificates() (certs []LocalCertificate, err error) {
}
// AddCertificate adds a certificate to this node's local certificate store (after verification).
func (n *Node) AddCertificate(cert *Certificate) error {
func (n *Node) AddCertificate(cert *Certificate, localTrust uint) error {
ccert := cert.cCertificate()
defer deleteCCertificate(ccert)
return certificateErrorToError(int(C.ZT_Node_addCertificate(n.zn, nil, C.int64_t(TimeMs()), C.uint(localTrust), (*C.ZT_Certificate)(ccert), nil, 0)))
}
// DeleteCertificate deletes a certificate from this node's local certificate store.
func (n *Node) DeleteCertificate(serialNo []byte) error {
if len(serialNo) != CertificateSerialNoSize {
return ErrInvalidParameter
}
C.ZT_Node_deleteCertificate(n.zn, nil, unsafe.Pointer(&serialNo[0]))
return nil
}
// -------------------------------------------------------------------------------------------------------------------