# Local cache validation pseudo code # (c) Geoff Huston, 2014 # # Input: # self_signed_ta_certificates # An array of objects that correspond to the # collection of self-signed certificates that correspond # to the selected set of trust anchors # # pass1 - assembly # foreach ta in (self_signed_ta_certificates) { # check the validity of the self-signed CA # if its valid then set its valid resource set to # the set listed in the cert # and process its subordinate certs # # validate_ta is an external routine that confirms that the # self-signed certificate was generated using a key pair whose # public key is part of the loaded trust key set if (validate_ta(ta)) { ta->valid_inr = ta->inr ; assemble(ta) ; } # if its invalid then do not head down the subordinate route # and set its valid resource set to empty else { ta->sia= (); ta->valid_inr = 0 ; } } # pass 2 - build intersection chains # foreach ta in (self_signed_ta_certificates) { # collect all certificates that are found at the SIA scan(ta) ; } # DONE # exit ################################################################ # assemble # # this routine retrieves subordinate certificates that are found at the URL # contained in the SIA of the parent certificate # # the retrieval could be a direct rsync operation, or, if rsync is performing # some form of module-based bulk extraction, then this could be a local operation # that assembles a set of certs from the local rsync store # # this routine uses one external certificate function # is_ca(a) - returns TRUE if a is a CA certificate # sub assemble(ca) { # the external function "retrieve" returns an array of certificates @sub_set = retrieve(ca->sia) ; # this set is referenced from the parent certificate data struct ca->sia_set = @sub_set ; # for each subordinate certificate foreach sub_cert (@sub_set) { # call the external routine validate_ca to check that # the certificate is valid according to RFC5280 (i.e. ignore RFC3779 # resource extensions at this point) if (is_ca(sub_cert) && validate_ca(ca,sub_cert)) { # and recurse down the tree if its a ca cert assemble(sub_ca) ; } sub_cert->valid_inr = () ; } } # scan # # this routine stores with each certificate the INR set that is defined as the # intersection of the certificate's listed INR resources and the INR set of the # certificate's parent # # this routine uses three external resource set functions: # intersect(a,b) - returns a set which is the union of the sets a and B # union(a,b) - returns a set which is the intersection of the sets a and b # equal(a,b) - returns TRUE if set a is equal to set b, FALSE otherwise # sub scan(ca) { @sub_set = ca->sia_set ; # If this cert has no subordinate products then we are done if (@sub_set == ()) return ; # for each subordinate certificate foreach sub_cert (@ca_set) { # perform certificate validation tests on sub_ca # - issuer / subject_name match # - valid dates # - crypto match on key if (validate_ca(ca,sub_cert)) { # store the intersection of the certificates lister INR resources and the # inr set of the certificate's parent inr_set = intersect(ca->valid_inr,sub_cert->inr) ; # if this is larger than the sub_cert valid resource set, then recurse down if (!equal(union(inr_set,sub_cert->valid_inr),sub_cert->valid_inr)) { sub_cert->valid_inr = union(inr_set,sub_cert->valid_inr) ; if (is_ca(sub_cert)) { scan(sub_ca) ; } } } } }